На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Serafim, fatalist
  
    > Спецификации PHP , rfc, psr etc...


      В данном разделе буду публиковать обновления, черновики и спецификации.

      Некоторые разработчики, что самое удивительное, до сих пор не в курсе стандартов PHP - им будет интересно про них прочитать (постараюсь скопипастить\перевести все в будущем). Ну а для хардкорных гуру PHP будут интересны тенденции развития PHP и планы на будущее.


      Версии:
      CI Статус: user posted image

      Windows binaries:

      > https://windows.php.net/download


      Стандарты:

      PHP-FIG (PHP Framework Interop Group). Ветка PSR (Proposing a Standards Recommendation):

      PSR-0: Описывает рекомендацию именования классов и пространств имён:
      оригинал: Описание (RU)
      перевод: Спецификации PHP (сообщение #3358162)

      PSR-1: Описывает базовую рекомендацию написания кода (Basic Code Style Guide):
      оригинал: Описание (RU)
      перевод: Спецификации PHP (сообщение #3358539)

      PSR-2: Описывает расширенную рекомендацию написания кода (Advanced Code Style Guide):
      оригинал: Описание (EN) Мета (EN)

      PSR-3: Описывает рекомендацию интерфейса логгирования кода (Logger Interface):
      оригинал: Описание (EN)

      PSR-4: Описывает автозагрузку классов. Можно считать рекомендацию, как расширяющую нулевой стандарт:
      оригинал: Описание (RU) Мета (RU) Примеры (RU)



      Обновлено 29 мая 2015

      Сообщение отредактировано: Serafim -

        Стандарт PSR-0: Автозагрузка

        Ниже описаны требования, которые следует соблюдать для обеспечения взаимодействия с автозагрузчиком.

        Обязательные
        Соглашения:
        Пространство - Namespace
        Подпространство - Sub-namespace
        Разработчик - Vendor name


        • Полное пространство имён должно иметь следующую структуру \<Разработчик>\(<Пространство имён>\)*<Название класса>
        • Каждое пространство имён должно начинаться с имени разработчика
        • Количество подпространств не регулируемо (т.е. на усмотрение разработчика)
        • При загрузке из файловой системы каждый разделитель в пространстве должен преобразовываться в DIRECTORY_SEPARATOR (прим. это глобальная константа в PHP)
        • Каждый символ нижнего подчёркивания, "_" - так же должен преобразовываться в DIRECTORY_SEPARATOR, но только если он находится в названии класса. Если символ нижнего подчёркивания, "_", находится в названии пространства имён - преобразований не требуется
        • При загрузке из файловой системы - следует использовать полное пространство имён с постфиксом .php
        • Буквы имени разработчика, пространств имён и классов - могут иметь произвольный регистр


        Примеры

        • ExpandedWrap disabled
            \Doctrine\Common\IsolatedClassLoader
                // преобразуется в
                // /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php

        • ExpandedWrap disabled
            \Symfony\Core\Request
                // преобразуется в
                // /path/to/project/lib/vendor/Symfony/Core/Request.php

        • ExpandedWrap disabled
            \Zend\Acl
                // преобразуется в
                // /path/to/project/lib/vendor/Zend/Acl.php

        • ExpandedWrap disabled
            \Zend\Mail\Message
                // преобразуется в
                // /path/to/project/lib/vendor/Zend/Mail/Message.php


        Подчёркивание в именах классов и пространствах имён

        • ExpandedWrap disabled
            \namespace\package\Class_Name
                // преобразуется в
                // /path/to/project/lib/vendor/namespace/package/Class/Name.php

        • ExpandedWrap disabled
            \namespace\package_name\Class_Name
                // преобразуется в
                // /path/to/project/lib/vendor/namespace/package_name/Class/Name.php

        Эти стандарты существуют для того, что бы было удобнее и проще организовывать классы для автозагрузки. Вы можете проверить соответствие Вашего кода стандарту, используя SplClassLoader (https://gist.github.com/jwage/221634) автозагрузчик для PHP 5.3+.


        Пример реализации

        ExpandedWrap disabled
          <?php
           
          function autoload($className)
          {
              $className = ltrim($className, '\\');
              $fileName  = '';
              $namespace = '';
              if ($lastNsPos = strrpos($className, '\\')) {
                  $namespace = substr($className, 0, $lastNsPos);
                  $className = substr($className, $lastNsPos + 1);
                  $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
              }
              $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
           
              require $fileName;
          }



        Реализация SplClassLoader

        Следующий автозагрузчик: https://gist.github.com/jwage/221634 является образцом алгоритма автозагрузки классов по стандарту PSR-0, который был описан выше. В настоящее время - это рекомендуемый способ автозагрузки классов PHP 5.3+, которые следуют этому стандарту.


        Вольный перевод от Serafim.
        Редакция от 23 мая 2013 года.
        Перевод от 23 сентября 2013 года.










        Стандарт PSR-1: Основные рекомендации написания кода

        Этот раздел включает в себя стандарты кодирования (написания кода), которые необходимы для обеспечения единообразия и чистоты PHP кода.

        Все ключевые слова, такие как "должно", "не должно", "рекомендуется" и прочее-прочее в данном документе следует интерпретировать, как описано в RFC 2119, но т.к. это русский перевод - данный пункт можно смело опускать из-за отсутствия согласованности в именовании на латинице и кириллице.

        Обзор
        • Php код должен содержать только теги <?php и <?=
        • Все файлы php должны быть в кодировке UTF-8 без BOM символа
        • Php Файл может содержать объявления классов, функций, методов и проч., либо выполнять побочные действия (вывод на экран, изменение ini конфигурации и проч.), но не должны содержать обе этих функциональности одновременно. (прим. Имеется ввиду разделение логических участков кода и отображения\изменение поведения и проч.)
        • Пространства имён и названия классов должны следовать стандарту PSR-0
        • Имена классов должны быть объявлены в StudlyCaps
        • Константы классов должны быть объявлены в верхнем регистре (Upper case), разрешено использовать символ нижнего подчёркивания (underscore) в качестве разделителя (слов).
        • Методы должны быть объявлены в camelCase



        Файлы
        PHP Теги
        Php код должен содержать только теги <?php ?> или укороченный вариант <?= ?>. Другие варианты использовать не следует.

        Кодировка
        Все файлы PHP должны быть в кодировке UTF-8 без BOM символа.

        Побочные действия - разделение кода (в оригинале: "Side Effects")
        • PHP файл должен содержать, либо объявление методов\классов\функций, либо только вывод в stdout
        • Фраза "побочные действия" (Side Effects) означает исполнение логики, не связанной непосредственно с объявлением классов, функций, констант и проч., в том числе запись в файл.
        • Побочные действия, могут включать, но не ограничиваются только выводом данных, инклудов (include\require), взаимодействие со сторонними сервисами, изменение настроек ini, отображение ошибок и исключений, изменение статических, либо глобальных переменных, чтение или запись в файл, и т.д.

        Ниже приведён пример обеих деклараций в одном файле, включающий "побочные действия", т.е. именно то, чего следует избегать.
        ExpandedWrap disabled
          <?php
          // побочное действие: изменение ini
          ini_set('error_reporting', E_ALL);
           
          // побочное действие: инклуд
          include "file.php";
           
          // побочное действие: вывод данных
          echo "<html>\n";
           
          // объявление функции
          function foo()
          {
              // тело функции
          }


        Далее показан пример без подобных побочных действий. Т.е. эталон. То, к чему следует стремиться.
        ExpandedWrap disabled
          <?php
          // объявление функции
          function foo()
          {
              // тело функции
          }
           
          // условные операторы не являются побочным действием
          if (! function_exists('bar')) {
              function bar()
              {
                  // тело функции
              }
          }




        Именование классов и пространств имён
        • Пространство имён и классы должны соблюдать стандарт PSR-0
        • Каждый класс должен находиться как минимум в одном пространстве имён, т.е. не должен находиться в корневом.
        • Имена классов должны быть объявлены в CamelCase (с заглавной буквы)
        • Код, написанный для PHP версии 5.2 и более ранних - должны использовать псевдо-пространства имён, например:
          ExpandedWrap disabled
            // PHP 5.3+
            namespace Vendor\Model;
            class Foo{}
             
            // PHP 5.2 или более ранние версии
            class Vendor_Model_Foo



        Константы классов, поля (в оригинале - свойства) и методы.
        прим. Под термином "класс" (class) подразумеваются не только классы, но и интерфейсы (interface), и трейты (traits)

        Константы
        Константы класса должны быть в верхнем регистре с нижним подчёркиванием в качестве разделителей, например:
        ExpandedWrap disabled
          namespace Vendor\Model;
          class Foo
          {
              const VERSION = '1.0';
              const DATE_APPROVED = '01-01-2042';
          }



        Поля (свойства)
        Хочу заметить, что в PHP отсутствуют свойства, точнее было перевести properties как "поля" (прим. переводчика)

        Данное руководство умышленно уклоняется от каких-либо рекомендаций в отношении использования $CamelCase, $camelCase или $under_score. Что бы ни использовалось - следует придерживаться этого стиля на протяжении всего кода.

        Однако всё же если есть возможность - рекомендую использовать именно $camelCase (начинается с нижнего регистра). Всё же это наиболее популярный формат именования переменных (прим. переводчика)


        Методы

        Методы должны быть объявлены в camelCase()


        Вольный перевод от Serafim.
        Редакция от 04 июня 2012 года.
        Перевод от 10 октября 2013 года.

        Сообщение отредактировано: Serafim -
          PHP 7.0, что нового?
          Должен выйти в октябре 2015 года



          - Теперь ключевые слова доступны для имён полей\свойств, методов, констант, классов, трейтов, интерфейсов:
          ExpandedWrap disabled
            callable
            class
            trait
            extends
            implements
            static
            abstract
            final
            public
            protected
            private
            const
            enddeclare
            endfor
            endforeach
            endif
            endwhile
            and
            global
            goto
            instanceof
            insteadof
            interface
            namespace
            new
            or
            xor
            try
            use
            var
            exit
            list
            clone
            include
            include_once
            throw
            array
            print
            echo
            require
            require_once
            return
            else
            elseif
            default
            break
            continue
            switch
            yield
            function
            if
            endswitch
            finally
            for
            foreach
            declare
            case
            do
            while
            as
            catch
            die
            self
            parent

          за исключением:
          ExpandedWrap disabled
            public
            protected
            private
            abstract
            final
            static
          - они НЕ доступны в качестве имён констант и методов,
          так же
          ExpandedWrap disabled
            class
          не доступно в качестве имени констант.


          - Теперь при преобразовании массива в строку будет выкидываться ошибка E_RECOVERABLE_ERROR (исключение, EngineException)


          - Теперь второй аргумент JSON_PRESERVE_ZERO_FRACTION в функции json_encode будет сохранять дробную часть значения в целых double переменных
          например 42.0, раньше принудительно кастовалось к 42


          - Удалены php4 конструкторы
          *методы с именем класса


          - Удален варнинг date.timezone


          - Добавлен оператор `<=>`
          Возвращает 1, 0 или -1 в зависимости от того, какой аргумент при сравнивании больше (1 <=> 2 == -1; 2 <=> 2 == 0; 2 <=> 1 == 1)


          - Из языка вырезаны мёртвые функции
          ExpandedWrap disabled
            // функции
            dl
            set_magic_quotes_runtime
            magic_quotes_runtime
            set_socket_blocking
            mcrypt_generic_end
            mcrypt_ecb
            mcrypt_cbc
            mcrypt_cfb
            mcrypt_ofb
             
            // методы и константы
            IntlDateFormatter::setTimeZoneID
            PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT
            CN_match и SNI_server_name из stream api
             
            // ini опции
            xsl.security_prefs
             
             
            // аргументы
            mktime() удалён $is_dst аргумент
            gmmktime() удалён $is_dst аргумент
            setlocale() удалён второй аргумент
            preg_replace() удалён eval флаг
             
            // прочее
            Комментирование с помощью `#` в .ini более не доступно
            Небезопасная загрузка с помощью curl более недоступна



          - Обновлено (Заменено) расширение JSON


          - Добавлена типизация возвращаемых значений
          ExpandedWrap disabled
            class Some
            {
                public function any(): array
                {
                    return [];
                }
            }

          Доступны как имена скаляров, так и имена классов (интерфейсов)


          - Удалены следующие SAPI расширения
          ExpandedWrap disabled
            aolserver
            apache
            apache_hooks
            caudium
            continuity
            isapi
            milter (скорее всего останется)
            phttpd
            pi3web
            roxen
            thttpd
            tux
            webjames
            apache2filter
            nsapi
            mssql
            pdo_oci
            sybase_ct
            mysql
            ereg



          - Добавлены юникод-вставки
          ExpandedWrap disabled
            echo "\u{1F602}";



          - Добавлен оператор `??`
          проверка на isset
          ExpandedWrap disabled
            // PHP <5.6
            echo isset($_GET['some']) ? $_GET['some'] : 23;
             
            // PHP >=7.0
            echo $_GET['some'] ?? 23;



          - Константы NAN, INF теперь кастуются к -9223372036854775808
          ранее к 0).


          - Поправлены бинарные сдвиги
          1 << -2 теперь возвращает 4611686018427387904 (ранее bool(false) и E_WARNING)
          8 >> 64 возвращает 8 (ранее 0), и т.д.


          - Теперь при переполнении PHP_INT_MAX (PHP_INT_MIN) будет возвращаться INF (-INF)


          - Добавлен AST
          Это значит, что стали валидными (и с нормальным поведением) такие выражения, как:
          ExpandedWrap disabled
            // Поддержка некоторых комбинаций операторов
            $foo()['bar']() // Вызов метода из элемента массива
            [$obj1, $obj2][0]->prop // Получение свойства из элемента массива
            getStr(){0} // Получение первого чара из метода
             
            // Расширенная (вложенная) поддержка оператора статики `::`
            $foo['bar']::$baz
            $foo::$bar::$baz
            $foo->bar()::baz()
             
            // Расширенная (вложенная) поддержка оператора вызова `()`
            foo()()
            $foo->bar()()
            Foo::bar()()
            $foo()()
             
            // Поддержка предыдущих операторов для оператора распаковки `...`
            (...)['foo']
            (...)->foo
            (...)->foo()
            (...)::$foo
            (...)::foo()
            (...)()
             
            // Несколько более вменяемых примеров
            (function() { ... })()
            ($obj->closure)()
             
            // Ну и все операторы с разыменованием скаляров (not very useful)
            "string"->toLower()
            [$obj, 'method']()
            'Foo'::$bar



          - Для объекта замыканий добавлен метод call
          Аналог bind\bindTo, но с перманентым уничтожением, очисткой памяти, после вызова


          - Для оператора list добавлена поддержка строк
          ExpandedWrap disabled
            list($a, $b) = 'ab'; // $a == 'a', $b == 'b' (ранее $a == $b == null)



          - Удалены все устаревшие открывающие (и закрывающие) php теги
          ExpandedWrap disabled
            <%
            <%=
            %>
            /<script\s+language\s*=\s*(php|"php"|'php')\s*>/
            /</script>/



          - Исправлена ошибка, позволяющая использовать несколько default в конструкции swtch


          - Вызов несуществующего метода теперь выкидывает E_RECOVERABLE_ERROR (исключение, EngineException) и доступен для перехвата


          - Теперь unserialize имеет возможность фильтрации данных, требуемых для десиарилизации


          - Теперь функция session_start([array $args]), определяет некоторые параметры
          Теперь сессия, по умолчанию, пишется только тогда, когда данные были изменены (добавлен аргумент lazy_write = false).
          Позволяет только читать сессию (read_only = false)


          - Удалена поддержка hex чисел в строках
          `(int)"0x123"` теперь не поддерживается


          - Добавлены исключения сравнения
          Добавлено исключение AssertionException, например при вызове assert($value, $exceptionString), где $value === false


          - Добавлена групповая (вложенная) декларация use (включая функции и прочее)
          ExpandedWrap disabled
            // Ранее
             
            use FooLibrary\Bar\Baz\ClassA;
            use FooLibrary\Bar\Baz\ClassB;
            use FooLibrary\Bar\Baz\ClassC;
            use FooLibrary\Bar\Baz\ClassD as Fizbo;
             
            // Сейчас
            use FooLibrary\Bar\Baz\ {
                ClassA,
                ClassB,
                ClassC,
                ClassD as Fizbo
            };



          - Добавлены исключения EngineException и ParseException, убраны аналогичные ошибки
          ExpandedWrap disabled
            E_ERROR
            E_CORE_ERROR
            E_COMPILE_ERROR
            E_USER_ERROR
             
            E_RECOVERABLE_ERROR
            E_PARSE
             
            E_WARNING
            E_CORE_WARNING
            E_COMPILE_WARNING
            E_USER_WARNING
             
            E_DEPRECATED
            E_USER_DEPRECATED
            E_NOTICE
            E_USER_NOTICE
            E_STRICT


          Иерархия:
          ExpandedWrap disabled
            BaseException (abstract)
                +- EngineException
                +- ParseException
                +- Exception
                    +- ErrorException
                    +- RuntimeException
                    +- ...
                +- ...



          === Добавлено 02.04.2015 ===

          - Добавлены хинтинги скалярных типов
          Это значит, что для всех аргументов можно указывать скаляры в качестве типов. По-умолчанию работает приведение типов, для того, чтоб вызывать исключения при несоответствии типа у аргумента - требуется использовать конструкцию: declare(strict_types=1);


          - Добавлена возможность использовать return вместе с генераторами и импортировать их из других методов
          Текущее поведение:
          ExpandedWrap disabled
            function bar()
            {
                yield 3;
            }
             
            function foo()
            {
                yield 1;
                yield 2;
                yield $this->bar();
            }
             
             
            foreach (foo() as $value) {
                echo print_r($value, 1) . "\n";
            }
             
            // 1
            // 2
            // Generator#object


          Исправляем ситуацию:

          В PHP нельзя создать объект Generator (Запрещено), пытаемся обойти вызов исключения в конструкторе, но Reflection + newInstanceWithoutContructor тоже не помогает (Class Generator is an internal class that cannot be instantiated without invoking its constructor), при этом сам класс финальный, т.е. от него нельзя наследоваться, а перенос методов из одного класса в другой (например с помощью Closure контейнера) работать не будет. Так что единственным вариантом остаётся использовать цикл.
          ExpandedWrap disabled
            function bar()
            {
                yield 3;
            }
             
            function foo()
            {
                yield 1;
                yield 2;
                foreach (bar() as $v) {
                    yield $v;
                }  
            }
             
            foreach (foo() as $value) {
                echo print_r($value, 1) . "\n";
            }
             
            // 1
            // 2
            // 3


          В PHP 7.0:
          ExpandedWrap disabled
            // 1 - можно использовать `return`, в качестве конечного значения
            // 2 - можно использовать `yield from` для импорта другого генератора
            // 3 - в объект генератора включён метод `getReturn()` для перехода сразу же к конечному значению (к return)
            function bar()
            {
                yield 3;
            }
             
            function foo()
            {
                yield 1; // вызывается первым
                yield 2; // вызывается вторым
                return yield from bar(); // вызывается третьим (переход в генератор функции bar)
            }
             
            foo(); // 1
            foo()->getReturn(); // 3


          - Добавили функцию для деления по модулю с проверкой на ноль
          Было предложено два варианта: Оператор "%%" и функция "intdiv", поведение их должно было быть одинаковым: `2 / 0` - выкидывает ошибку, так же как и `2 % 0`, оператор `2 %% 0` возвращает false, так же как и `intdiv(2, 0)`.
          Предложение по оператору не прошло голосования (5 за, 24 против), а функция была принята единогласно.



          Редакция от 02 апреля 2015 года.

          https://wiki.php.net/rfc

          Сообщение отредактировано: Serafim -
            # reserved
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0921 ]   [ 15 queries used ]   [ Generated: 28.03.24, 12:17 GMT ]