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

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

  Все выпуски  

Модификаторы доступа


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

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

The Pterodactyl

Copyright 2006 Pterodactyl's School

17.01.2006

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

Аннотация

Подробно рассмотрены модификаторы доступа к переменным и методам класса, управляющие их видимостью, - public, protected и private. Даны рекомендации по их использованию. Продолжена практическая разработка учебного приложения с использованием изученного материала.


Видимостью переменных и методов класса в PHP 5 можно управлять при помощи модификаторов доступа public, protected и private, предваряющих объявление переменной или метода (Таблица 1, «Видимость и модификаторы доступа»). В более ранних версиях PHP все переменные и методы были публичными (общедоступными).

Таблица 1. Видимость и модификаторы доступа
Видимость public protected private
Извне класса Да Нет Нет
Из того же класса Да Да Да
Из унаследованного класса Да Да Нет

Защищенные переменные и методы видны как из того класса, в котором они определены, так и из унаследованных классов; однако, они не видны извне этих классов (Пример 2, «Доступ к защищенной переменной»).

При попытке непосредственного доступа к защищенной переменной возникает фатальная ошибка.

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

При попытке непосредственного доступа к приватной переменной возникает фатальная ошибка. Попытка получить значение приватной переменной из класса-наследника приводит к неопределенному (undefined) результату из-за обращения к несуществующей переменной (родительская приватная переменная оттуда попросту не видна).

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

Переменные и методы, не будучи предваренными одним из модификаторов доступа, по умолчанию являются публичными (Пример 5, «Доступ по умолчанию»). Такое же правило распространяется на переменные, объявленные в стиле PHP 4 - с использованием ключевого слова var.

Внимание

Не следует использовать устаревшее ключевое слово var при объявлении переменных класса, если только не требуется обеспечить совместимость с PHP 4.

При разработке классов следует стремиться к максимальной скрытости их переменных и методов от внешнего доступа. В развернутом виде это правило может быть сформулировано следующим образом.

  1. Все переменные должны быть приватными или, если их необходимо перекрывать в наследующем классе, - защищенными. Внешний доступ к таким переменным следует осуществлять при помощи публичных методов.
  2. Методы могут быть публичными, если к ним требуется доступ извне. Остальные методы должны быть приватными или защищенными.

Соблюдение перечисленных требований позволяет уменьшить риск возникновения ошибок и непредсказуемого поведения объектов в результате несанкционированного внешнего вмешательства в их работу.

На текущем практическом занятии продолжим разработку класса SSS (см. Доработка класса SSS). Нам предстоит решить следующие задачи.

  1. Устранить недостаток, допущенный ранее при перекрытии значений массива аттрибутов страницы.
  2. Расширить набор перекрываемых аттрибутов.

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

  1. Обновите текущую версию.

    * @version   0.02
  2. Устранение недостатка с перекрытием аттрибутов страницы

    Проблема состоит в том, что в версии 0.01 значение аттрибута tab по умолчанию, равное четырем пробелам, устанавливается безусловно.

    function __construct($attributes) {
        $attributes['tab'] = '    ';
        /* ... */
    }
                    

    Тем самым, пользователь лишается возможности установить свое значение.

    Можно было бы проверять, установлен ли этот аттрибут в наборе, получаемом конструктором.

    if (empty($attributes['tab'])) {
        $attributes['tab'] = '    ';
    }
                    

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

    А вот функция array_merge, оказывается, как нельзя лучше удовлетворяет поставленной задаче. Она совмещает элементы нескольких массивов в одном, заменяя значения одинаковых элементов более "поздними".

    <?php
    
    $x = array('a' => '1', 'b' => '2', 'c' => '3');
    $y = array('a' => 'A', 'foo' => 'bar');
    $z = array_merge($x, $y);
    print_r($z);
    
    ?>
    
                    
    Array ( [a] => A [b] => 2 [c] => 3 [foo] => bar )
    1. Добавьте приватную переменную $attributes, которая содержала бы массив значений по умолчанию для аттрибутов страницы, получаемых конструктором класса. Эти аттрибуты перекрывают значения по умолчанию, установленные в родительском классе.

          /**
           * Contains defaults for page attributes
           * Overrides parent class defaults
           *
           * @var array
           * @access private
           * @since 0.02
           */
          private $attributes = array('tab' => '    ');
                              
    2. Назначьте для аргумента конструктора значение по умолчанию (пустой массив).

      function __construct($attributes = array())
    3. Перепишите в конструкторе класса вызов родительского конструктора.

              $attr = array_merge($this->attributes, $attributes);
              parent::__construct($attr);
                              
    4. Внесите изменения во встроенную документацию конструктора.

      1. Удалите строку '@todo'.

      2. Замените строку 'Overrides the tab attribute'.

             * Overrides page attributes
  3. Расширение набора перекрываемых аттрибутов

    Класс HTML_Page2 позволяет устанавливать для страницы целый ряд других аттрибутов, но уже не в конструкторе, а путем вызова соответствующих методов. Так, например, могут быть добавлены разнообразные мета данные, страницы стилей, скрипты и т. п. В целом все эти аттрибуты являются опциональными (не обязательными), но, по меньшей мере, для двух из них имеет смысл установить значения по умолчанию, чтобы избежать необходимости устанавливать их каждый раз при разработке конкретных приложений.

    Большинство приложений используют хотя бы одну внешнюю страницу стилей. Обычно это файл styles.css, расположенный в корневой директории сайта.

    Специальный графический значок (иконка) используется на сайтах далеко не всегда; однако, целесообразность его использования довольно высока, а название и расположение достаточно стандартизовано (/favicon.ico), чтобы этот аттрибут был включен в наш список.

    Для предотвращения возникновения ошибочных ситуаций следует предусмотреть проверку доступности указанных файлов.

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

    1. Добавьте приватную переменную $options, которая содержала бы массив значений по умолчанию для дополнительных аттрибутов страницы.

          /**
           * 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');
                              
    2. Добавьте при вызове конструктора дополнительный аргумент $options, по умолчанию принимающий значение пустого массива и внесите соответствующие дополнения во встроенную документацию.

           * 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)
                              
           * @param   array   $options        Extra page attributes
           * @since   0.02
                              
      function __construct($attributes = array(), $options = array())
    3. Разработайте приватный метод isFileExists, который будет проверять наличие заданного файла. Необходимость разработки отдельного метода обусловлена тем, что путь к файлу может быть как абсолютным (начиная от корневой директории сайта), так и относительным (начиная от текущей директории). В первом случае аргумент метода следует присоединить к физическому пути на сервере к корневой директории сайта ($_SERVER['DOCUMENT_ROOT']), во втором - ничего менять не нужно.

          /**
           * 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
                              
    4. Добавьте в конструктор обработку дополнительных аттрибутов. Не забудьте удалить устаревшую строку из версии 0.01 с вызовом метода setMetaData и строку 'Sets the Generator meta data' из встроенной документации.

              $opt = array_merge($this->options, $options);
              $this->setTitle($opt['title']);
              $this->setMetaData('Generator', $opt['generator']);
              if ($this->isFileExist($opt['stylesheet'])) {
                  $this->addStyleSheet($opt['stylesheet']);
              }
              if ($this->isFileExist($opt['favicon'])) {
                  $this->addFavicon($opt['favicon']);
              }
                              

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

Пример 6. SSS 0.02

<?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.02
 * @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 {
    /**
     * 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

    /**
     * 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
}

?>

            

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

Чтобы использовать новую версию разрабатываемого класса, несколько видоизменим скрипт, который был применен для предыдущей версии (Пример 7, «Использование SSS 0.02»).

Обратите внимание на появление переменной $options, передаваемой в качестве параметра при создании нового объекта класса SSS, и исчезновение вызова метода setTitle.

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

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

Это просто тест.

<?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.02 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

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


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

В избранное