Отправляет email-рассылки с помощью сервиса Sendsay

PHP 5: Новые возможности.

  Все выпуски  

Статические методы и свойства


Информационный Канал Subscribe.Ru

PHP 5: Новые возможности.

The Pterodactyl

Copyright 2006 Pterodactyl's School

24.01.2006

История переиздания
Издание 1.00 24.01.2006
Первоначальная версия.

Аннотация

Рассказано о статических методах и переменных, а также о константах класса. Доработано учебное приложение. Начато знакомство с пакетом PEAR::HTML_Template_Flexy.


Для того, чтобы объявить статический метод или свойство (переменную класса), используется ключевое слово static. Оно должно следовать сразу же после модификатора доступа. Если модификатор доступа отсутствует, то объявление начинается с ключевого слова static, а видимость метода или переменной по умолчанию принимается общедоступной (public).

Статические методы и переменные принадлежат самому классу, но не его экземплярам (объектам). Поэтому для доступа к таким методам и переменным не требуется создание объекта.

Поскольку статические методы принадлежат всему классу, а не отдельным его экземплярам, то и вызывать их необходимо в контексте класса (Пример 1, «Вызов статического метода»). Для этого используется оператор :: вне класса либо специальное название self внутри самого класса.

Вызов в контексте объекта также возможен, но пользоваться им не следует (Пример 2, «Нежелательный вызов методов»). Не нужно также вызывать в контексте класса (статически) обычные методы - это вызовет предупреждение уровня E_STRICT.

Внимание

Псевдопеременная $this внутри статических методов недоступна, а попытка ее использования вызывает фатальную ошибку.

<?php

class Foo {
    private $hello = 'Hello there!';

    static function printHello()
    {
        print $this->hello; // FATAL ERROR
    }
}

Foo::printHello();

?>
            
Fatal error: Using $this when not in object context

Статические переменные часто называют свойствами класса в противоположность обычным свойствам объектов.

Как и статические методы, статические переменные достижимы при помощи оператора :: извне или специального названия self изнутри класса (Пример 3, «Использование статической переменной»).

Внимание

К статическим переменным нельзя обратиться в контексте объекта (в отличие от статических методов, которые, хоть им и не рекомендуется пользоваться, но все же поддерживают такой способ обращения).

<?php

class Foo {
    public static $staticVariable = 'static';
}

$foo = new Foo;
print $foo->staticVariable; // you should use Foo::$staticVariable

?>
            
Notice: Undefined property: Foo::$staticVariable

Глобальные константы, объявляемые при помощи функции define(), существовали в PHP и ранее. Тем не менее, только PHP 5 предоставляет возможность объявления констант в контексте класса.

Своей принадлежностью непосредственно классу (а не объектам) и способами обращения к ним (:: или self) константы класса напоминают статические переменные. Однако, в отличие от последних, константы не содержат в начале названия символ $ и, будучи единожды объявленными, не могут быть изменены или удалены.

Обычно константы класса используются для перечисления тех или иных постоянных свойств (Пример 4, «Использование констант»).

Замечание

В названиях констант принято использовать заглавные буквы. Отдельные слова разделяются знаком подчеркивания.

На текущем практическом занятии нам предстоит выполнить две задачи.

  1. "Научить" разрабатываемое нами учебное приложение различать свою собственную версию.
  2. Познакомиться с пакетом PEAR::HTML_Template_Flexy.

Родительский класс - HTML_Page2 - имеет метод apiVersion() (Пример 5, «Функция HTML_Page2::apiVersion()»), который перекрывает аналогичный метод в классе HTML_Common, которому наследует HTML_Page2. Можно было бы просто перекрыть этот метод в классе SSS, однако, такой путь имеет один существенный недостаток: метод apiVersion() не является статическим, то есть, принадлежит объекту, а не классу. Версия же является как раз таким свойством, которое имеет смысл в контексте класса. Кроме того, представляется не самым удачным решение указывать версию непосредственно в самом методе.

Можно легко разрешить указанные противоречия, используя только что полученные знания о статических методах и константах (Доработка класса SSS).

Процедура 1. Доработка класса SSS

  1. Исправьте номер версии во встроенной документации.

     * @version 0.03
  2. Добавьте константу VERSION.

        /**
         * The current version
         *
         * @since 0.03
         */
        const VERSION = 0.03;
                        
  3. Добавьте статический метод getVersion().

        /**
         * Returns the current version
         *
         * @static
         * @access public
         * @return double
         * @since 0.03
         */
        public static function getVersion()
        {
            return self::VERSION;
        } // end func getVersion
                        
  4. Перекройте также метод apiVersion(), чтобы избежать вывода версии, относящейся к родительскому классу, объявив его использование нежелательным (deprecated).

    
        /**
         * Returns the current API version
         *
         * @access public
         * @return double
         * @since 0.03
         * @deprecated  Method deprecated since version 0.03
         */
        function apiVersion()
        {
            return self::getVersion;
        } // end func apiVersion
                        

В результате должен получиться следующий документ.

Пример 6. SSS 0.03

<?php

/**
 * The main part of the Simple Site Solution package
 *
 * The SSS package provides a simple interface for generating an web site.
 *
 * Required: PEAR::HTML_Page2.
 *
 * PHP version 5
 *
 * LICENSE: This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * @package    SSS
 * @author     The Pterodactyl <ptero@pterodactyl.l2p.net>
 * @copyright  2006 Pterodactyl's School
 * @license    http://www.gnu.org/licenses/gpl.txt  GNU General Public License
 * @version    0.03
 * @link       http://pterodactyl.l2p.net/php5/examples/SSS
 */
    
/**
 * Include the parent class
 */
require_once 'HTML/Page2.php';
    
/**
 * Advanced (X)HTML Page Generation Class
 *
 * Features:
 *  + PEAR Code Standards compliance
 *
 * Usage:
 *  require_once 'SSS.php';
 *  $page = new SSS;
 *  $page->setBody('...');
 *  $page->display();
 *
 * @todo    more features
 */
class SSS extends HTML_Page2 {
    /**
     * The current version
     *
     * @since 0.03
     */
    const VERSION = 0.03;
    
    /**
     * Contains defaults for page attributes
     * Overrides parent class defaults
     *
     * @var array
     * @access private
     * @since 0.02
     */
    private $attributes = array('tab' => '    ');
    
    /**
     * Contains defaults for extra page attributes
     *
     * @var array
     * @access private
     * @since 0.02
     */
    private $options = array('stylesheet' => '/styles.css',
        'favicon' => '/favicon.ico', 'title' => 'SSS',
        'generator' => 'Simple Site Solution');
    
    /**
     * Class constructor
     *
     * Accepts an array of attributes
     * (just as the parent) and options
     * Supported extra attributes:
     *  + stylesheet    Style sheet     (addStyleSheet)
     *  + favicon       Favorite icon   (addFavicon)
     *  + generator     Page generator  (setMetaData)
     *  + title         Page title      (setTitle)
     *
     * Calls the parent's constructor
     * Overrides page attributes
     *
     * @param   array   $attributes     Page attributes
     * @param   array   $options        Extra page attributes
     * @since   0.02
     */
    function __construct($attributes = array(), $options = array())
    {
        $attr = array_merge($this->attributes, $attributes);
        parent::__construct($attr);
    
        $opt = array_merge($this->options, $options);
        $this->setTitle($opt['title']);
        $this->setMetaData('Generator', $opt['generator']);
        if ($this->isFileExists($opt['stylesheet'])) {
            $this->addStyleSheet($opt['stylesheet']);
        }
        if ($this->isFileExists($opt['favicon'])) {
            $this->addFavicon($opt['favicon']);
        }
    } // end class constructor
    
    /**
     * Returns the current version
     *
     * @static
     * @access public
     * @return double
     * @since 0.03
     */
    public static function getVersion()
    {
        return self::VERSION;
    } // end func getVersion
    
    /**
     * Returns the current API version
     *
     * @access public
     * @return double
     * @since 0.03
     * @deprecated  Method deprecated since version 0.03
     */
    function apiVersion()
    {
        return self::getVersion;
    } // end func apiVersion
    
    /**
     * Checks out whether the file exists
     * The path to the file can be either absolute (from the
     * document root) or relative
     *
     * @param   string  $filename     The file name
     * @return  boolean
     * @access  private
     * @since   0.02
     */
    private function isFileExists($filename)
    {
        if ($filename[0] == '/') {
            $basedir = rtrim($_SERVER['DOCUMENT_ROOT'], '/');
        } else {
            $basedir = '';
        }
    
        return file_exists($basedir.$filename);
    } // end func isFileExists
}

?>

                

На сайте этот код находится здесь.

Пакет HTML_Template_Flexy представляет собой один из наиболее мощных и гибких инструментов для работы с шаблонами. Нам предстоит установить этот пакет на сайте (Установка пакета HTML_Template_Flexy) и применить его для подготовки тела страницы, генерируемой нашим учебным приложением (Использование HTML_Template_Flexy).

Процедура 2. Установка пакета HTML_Template_Flexy

  1. Скачайте и разархивируйте пакет.

    1. На странице загрузки выберите последнюю версию пакета.

    2. Для распаковки воспользуйтесь любым архиватором, поддерживающим формат .tgz (tar + gzip).

  2. Создайте на сайте каталог /pear/HTML/Template/.

  3. Закачайте следующие файлы на свой сайт в каталог /pear/HTML/Template/.

    1. Файл Flexy.php.

    2. Весь каталог Flexy целиком.

Процедура 3. Использование HTML_Template_Flexy

  1. Создание структуры каталогов

    Понадобятся два каталога: один для хранения разработанных нами шаблонов, а второй - для автоматически сгенерированного на основе этих шаблонов PHP кода.

    1. Создайте каталог templates для хранения шаблонов.

    2. Создайте каталог templates/compiled для хранения автоматически сгенерированного кода.

      Внимание

      Обеспечьте возможность автоматической записи в этот каталог, установив права доступа равными 0777 (пользователи Windows могут не беспокоиться).

  2. Создание шаблона

    Создайте шаблон templates/index.htm.

    <p>Этот шаблон со временем будет наполнен реальным содержимым.</p>
  3. Доработка демонстрационного скрипта

    Понадобится внести ряд изменений и дополнений в код скрипта, использованного для демонстрации предыдущей версии учебного приложения (Пример 7, «Демонстрационный скрипт»).

    1. Определите пути к каталогам, используемым для хранения шаблонов и кода[1].

      $dirs = array('templateDir' => 'templates',
          'compileDir' => 'templates/compiled');
                                  
    2. Включите файл HTML/Template/Flexy.php.

      require_once 'HTML/Template/Flexy.php';
    3. Создайте новый объект класса HTML_Template_Flexy, передав ему пути к каталогам в качестве параметра.

      $flexy = new HTML_Template_Flexy($dirs);
    4. Произведите компиляцию шаблона.

      $flexy->compile('index.htm');
    5. Получите содержимое страницы при помощи метода bufferedOutpitObject, передав ему в качестве параметра "пустой" объект.

      $content = $flexy->bufferedOutputObject(new stdClass);
    6. Установите тело страницы.

      $page->setBody($content);

Этот код на сайте можно найти здесь.

Получим следующее.

Этот шаблон со временем будет наполнен реальным содержимым.

<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
<head>
    <meta name="Generator" content="Simple Site Solution" />
    <title>SSS 0.03 Demo Page</title>
    <link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" />

    <link rel="stylesheet" href="/styles.css" type="text/css" />
</head>
<body>
    <p>Этот шаблон со временем будет наполнен реальным содержимым.</p>
</body>
</html>
            

Created with DocBook Created with Libxslt



[1] В реальном скрипте эти пути могут отличаться от указанных в примере.

С последней версией этой и других статей Вы можете ознакомиться на сайте рассылки [http://pterodactyl.l2p.net/php5/].


Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: inet.webbuild.php5whatsnew
Архив рассылки
Отписаться Вебом Почтой
Вспомнить пароль

В избранное