Как может выглядеть PHP 5.5

Original author: Nikita Popov
  • Translation
PHP 5.4 был опубликован четыре месяца назад, так что, вероятно, слишком рано смотреть на новую версию PHP. Тем не менее я бы хотел сделать для всех, кто не подписан на внутренний список рассылок, небольшой предварительный обзор того, как может выглядеть PHP 5.5.

Однако необходимо понять: PHP 5.5 еще на ранней стадии развития, поэтому никто не знает, как он будет выглядеть в итоге. Все, о чем здесь написано это только предложения. Я уверен, что не все это будет в PHP 5.5, или будет, но не в таком виде.

Так что не стоит слишком возбуждаться.

Теперь, без лишних церемоний, список фич, над которыми ведется работа в PHP 5.5:

Обратная совместимость


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

Отказ от поддержки Windows XP и 2003

Статус: landed; Ответственный: Pierre Joye

PHP 5.5 больше не поддерживает Windows XP и 2003. Этим системам около десяти лет, поэтому PHP отказалось от них.

Модификатор /e признан устаревшим

Статус: landed; Ответственный: Nikita Popov

Модификатор e указывает функции preg_replace выполнить заменяемую строку как код PHP, а не просто сделать замену. Неудивительно, что такое поведение является постоянным источником проблем, в том числе проблем безопасности. Именно поэтому использование этого модификатора выдаст предупреждение deprecated в PHP 5.5. В качестве замены необходимо использовать функцию preg_replace_callback. Вы можете найти более подробную информацию об этом изменении в соответствующем RFC.

Новые функции и классы


Далее мы рассмотрим некоторые запланированные новые функции и классы:

boolval()

Статус: landed; Ответственный: Jille Timmermans

В PHP уже реализованы функции strval, intval и floatval. Для согласованности добавлена функция boolval. Она делает то же самое, что и приведение (bool), но может быть использована в качестве аргумента для другой функции.

hash_pbkdf2()

Статус: landed; Ответственный: Anthony Ferrara

PBKDF2 означает «Password-Based Key Derivation Function 2» и, как можно понять из названия, это алгоритм для получения ключа шифрования из пароля. Она необходима для алгоритмов шифрования, но может быть использована и для хэширования паролей. Более подробное описание и примеры использования в RFC.

Добавления в расширении intl

Статус: landed; Ответственный: Gustavo André dos Santos Lopes

Будет много улучшений в расширение intl. Например, появятся новые классы IntlCalendar, IntlGregorianCalendar, IntlTimeZone, IntlBreakIterator, IntlRuleBasedBreakIterator, IntlCodePointBreakIterator. Я к сожалению не много знаю о расширении intl, так что, если вы хотите узнать больше, я рекоммендую ознакомиться с анонсами в список рассылки для Calendar и BreakIterator.

array_column()

Статус: proposed; Ответственный: Ben Ramsey

Существует предложение новой функции array_column (или array_pluck), которая будет вести себя следующим образом:

<?php

$userNames = array_column($users, 'name');
// тоже самое что
$userNames = [];
foreach ($users as $user) {
    $userNames[] = $user['name'];
}

Это как выборка столбца из базы данных, только для массивов.

Простой API для хеширования пароля

Статус: proposed; Ответственный: Anthony Ferrara

Недавняя утечка паролей (из LinkedIn и др.) показали, что даже крупные сайты не используют правильное хэширование паролей. Люди много лет выступают за использование BCrypt, но все же большинство людей, похоже, используют совершенно небезопасный sha1 хэш.

Мы полагали, что причиной этого может быть очень трудное использование функции crypt. Таким образом, мы хотели бы представить новый, простой API для безопасного хэширования пароля:

<?php

$password = "foo";

// создание хеша
$hash = password_hash($password, PASSWORD_BCRYPT);

// проверка пароля
if (password_verify($password, $hash)) {
    // пароль верный!
} else {
    // пароль неверный!
}

Новый API для хэширования имеет больше возможностей, все они изложены в RFC.

Изменения в языке


Теперь перейдем к действительно интересным вещам: новые возможности и усовершенствования языка.

Разыменование массивов

Статус: landed; Ответственный: Xinchen Hui

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

<?php

function randomHexString($length) {
    $str = '';
    for ($i = 0; $i < $length; ++$i) {
        $str .= "0123456789abcdef"[mt_rand(0, 15)]; // dereference для строки
    }
}

function randomBool() {
    return [false, true][mt_rand(0, 1)]; // dereference для массива
}

Я не думаю, что эта функция очень полезна на практике, но это делает язык согласованнее. См. также RFC.

empty() работает с вызовами функций и другими выражениями

Статус: landed; Ответственный: Nikita Popov

В настоящее время конструкция языка empty() может быть использована только с переменными, но не с выражениями. Например, код empty($this->getFriends()) выдаст ошибку. В PHP 5.5 это будет валидный код. Для получения дополнительной информации см. RFC.

Получение полного имени класса

Статус: proposed; Ответственный: Ralph Schindler

В PHP 5.3 представили пространства имен с возможностью назначать классам и пространствам имен более короткие псевдонимы. Это не распространяется на строку с именем класса:

<?php

use Some\Deeply\Nested\Namespace\FooBar;

// не работает, потому что будет использован глобальный класс `FooBar`
$reflection = new ReflectionClass('FooBar');

В качестве решения предложен новый синтаксис FooBar::class, который возвращает полное имя класса:

<?php

use Some\Deeply\Nested\Namespace\FooBar;

// работает, потому что FooBar::class интерпретируется в "Some\\Deeply\\Nested\\Namespace\\FooBar"
$reflection = new ReflectionClass(FooBar::class);

Больше примеров в RFC.

Пропуск параметров

Статус: proposed; Ответственный: Stas Malyshev

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

Возьмем пример функции из RFC:

function create_query($where, $order_by, $join_type='', $execute = false, $report_errors = true) { ... }

Нет никакого способа установить $report_errors = false без повторения двух других значений по умолчанию. Для решения этой проблемы предлагается использовать пропуск параметров:

create_query("deleted=0", "name", default, default, false);

Лично мне не особенно нравится это предложение. На мой взгляд код, в котором это нововведение необходимо, является плохо продуманным. Функции не должны иметь 12 дополнительных параметров.

Контроль типа для скалярных значений

Статус: proposed; Ответственный: Anthony Ferrara

Контроль типа для скалярных значений изначально планировался в 5.4, но его не сделали из-за отсутствия консенсуса. Для получения дополнительной информации о том, почему его еще не сделали в PHP, см.: Scalar typehints are harder than you think.

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

Оно будет работать, приводя входящее значение в указанный тип, но только если приведение может происходить без потери данных. Например 123, 123.0, "123" будут действительны для int параметров, но "привет мир" не будет. Это соответствует поведению внутренних функций.

function foo(int $i) { ... }

foo(1);      // $i = 1
foo(1.0);    // $i = 1
foo("1");    // $i = 1
foo("1abc"); // пока не ясно, может быть $i = 1 с выводом notice
foo(1.5);    // пока не ясно, может быть $i = 1 с выводом notice
foo([]);     // ошибка
foo("abc");  // ошибка

Getters и setters

Статус: proposed; Ответственный: Clint Priest

Если вы не поклонник писать все эти методы getXYZ() и setXYZ($value), то это должно быть позитивным изменением для вас. Предложение добавляет новый синтаксис для определения того, что должно произойти, когда свойство пишут или читают:

<?php

class TimePeriod {
    public $seconds;

    public $hours {
        get { return $this->seconds / 3600; }
        set { $this->seconds = $value * 3600; }
    }
}

$timePeriod = new TimePeriod;
$timePeriod->hours = 10;

var_dump($timePeriod->seconds); // int(36000)
var_dump($timePeriod->hours);   // int(10)

Есть еще ​​несколько нововведений, например read-only свойства. Если вы хотите узнать больше, посмотрите RFC.

Генераторы

Статус: proposed; Ответственный: Nikita Popov

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

Например, вот как можно определить функцию range как итератор:

<?php

function *xrange($start, $end, $step = 1) {
    for ($i = $start; $i < $end; $i += $step) {
        yield $i;
    }
}

foreach (xrange(10, 20) as $i) {
    // ...
}

Приведенная выше функция xrange имеет такое же поведение, как встроенная функция range с одним отличием: вместо возвращения массива со всеми значениями, она возвращает итератор, который генерирует значения на лету.

Для более глубокого введения в тему можно посмотреть RFC.

Выделение списков и выражения-генераторы

Статус: proposed; Ответственный: Nikita Popov

Выделение списков обеспечивают простой способ произвести операции над массивами:

$firstNames = [foreach ($users as $user) yield $user->firstName];

Выше приведенный код эквивалентен следующему:

$firstNames = [];
foreach ($users as $user) {
    $firstNames[] = $user->firstName;
}

Также можно фильтровать массивы следующим образом:

$underageUsers = [foreach ($users as $user) if ($user->age < 18) yield $user];

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

Дополнительные примеры в анонсе в списке рассылки.

Заключение


Как вы видите, есть много удивительных вещей, над которыми ведется работа в PHP 5.5. Но, как я уже сказал, PHP 5.5 еще молод, поэтому мы не знаем наверняка, что будет в нем, а что нет.

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

Комментарии приветствуются!
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 316

    +18
    Как же я буду рад, если это все произойдет!
      +5
      Произойти должно не это. Авторы должны посмотреть как используют их язык и сделать все возможное что бы облегчить его использование. А сейчас в тренде у нас, например, аннотации, ради которых приходится парсить комментарии. Но конечно же, зачем думать как сделать нормальным данный механизм, сообщество еще пять лет будет одним глазом в доку смотреть, другим в код — это же так удобно. Они лучше пропуск параметров запилят
        0
        Нельзя сказать, что не смотрят на использование. Свойства вон добавляют. А то меня каждый раз передёргивает, когда ради свойств я парсю строчки.
          +1
          Свойства это дальнейшее развитие __get/__set которым уже много-много лет. А «аннотации» появились недавно — по сути команда доктрины второй их перетащила в язык
            +4
            «Магические» методы, оперирующие на строчках — это кривые костыли, и ничего более. Это не развитие, а переосмысление.
              0
              Вот не прошло и десяти лет, как они это поняли. Слишком медленно до них доходит, что клевые фишки облечающие написание кода надо обязательно тащить из других языков и делать не менее круто.
          +4
          Так кто мешает влиться в разработку или обсуждение?

          php.net/mailing-lists.php
            –9
            Я думаю за меня уже все решили: openjdk.java.net/projects/lambda/ ;)

            Да и если что, Scala есть.
              +4
              Тогда непонятно, зачем столько негодования и рассказов, что авторы языка должны делать.
                +1
                Может потому, что данный язык не так давно был моим основным и мне интересно дальнейшее его развитие даже не смотря на то, что я вряд-ли когда-нибудь к нему вернусь?
                  +3
                  Вам просто интересно развитие, а нам на нём писать. Но вы указываете авторам что они должны делать для себя и для нас. Напоминает позицию эмигрантов, из-за границы указывающих как нам тут жить. Нормально?
            +1
          +11
          yield очень порадовал!
            0
            Ага, это уже давняя мечта. С того момента, как увидел это в питоне.
              +3
              После этого всего останется добавить строгую типизацию и приделать компилятор =)
                +4
                Ну зачем же писать самим, генерить байткод для jvm и llvm
                  0
                  Чем не устраивают существующие кэши опкода или хипхоп?
                    0
                    В хипхопе очень много проблем, в нем развивают только те фичи, которые нужны Facebook.

                    Если, допустим, затачивать новый проект конкретно под хипхоп — еще вариант, то с компиляцией старых больших проектов, так сказать, пичалька.
                      0
                      А вы думаете, что в случае появления нативной компиляции и статической типизации старые большие проекты не придётся переписывать?
                        0
                        Статическая типизация может быть необязательной. По дефолту тип а-ля variant, а указал конкретно integer или string будь добр соответствовать. Такой опыт уже есть с var vs public/protected/private или тем же typ hinting.
                        0
                        Ммм, компилировал ряд больших старых проектов хипхопом, не умер.
                        Из проблем только то, что пришлось ряд расширений PHP портировать под хипхоп (и что сторонние расширения хипхоп без плясок не подключает). В остальном никаких проблем. Каких фич не хватает?
                          +1
                          eval? :)
                            0
                            ЕМНИП, даже его в специальном режиме можно включить.
                      0
                      type hinting для всех типов данных решит, имхо, бОльшую часть проблем, которую решает статическая типизация.
                  +13
                  function create_query($where, $order_by, $join_type='', $execute = false, $report_errors = true) { ... }

                  Нет никакого способа установить $report_errors = false без повторения двух других значений по умолчанию. Для решения этой проблемы предлагается использовать пропуск параметров:

                  create_query("deleted=0", "name", default, default, false);


                  Думаю, не сильно этот синтаксис поможет.

                  Сделали бы уже как в питоне create_query("deleted=0", "name", $report_errors=false);, было бы круто.
                    +1
                    Согласен
                      0
                      Именно так — нельзя, так как будет конфликтовать с текущим поведением. Скорее уж как-то так:
                       create_query("deleted=0", "name", "report_errors"=>false)
                      
                        +4
                        И в случае переименовывания параметров этого метода придется переписывать весь код, который его использовал? На фиг… «default» в этом плане гораздо нагляднее.
                          0
                          Если меняется api, то код тоже, скорее всего, поменяется
                            +2
                            Может поменяться только имя параметра.
                            • UFO just landed and posted this here
                                +7
                                Рефакторинг
                                • UFO just landed and posted this here
                                    0
                                    Почему в рамкать рефакторинга может поменяться имя переменной в заголовке, но не может поменятся название метода?
                                      0
                                      Всё, что внутри метода относится к внутренней реализации и внешний код не должно волновать как называется параметр функции — $cnt или $totalPages.

                                      Переименование может быть выполнено для большей ясности (придумали более чёткое/правильное название), или в случае выноса части функционала в другие внутренние методы, когда в таком контексте эта переменная уже принимает некий другой смысл (более чёткий, или наоборот более общий), выполняя при этом ту же функцию.

                                      В общем, для лучшей внутренней читаемости кода может потребоваться переименование внутренней реализации. Тем кто использует этот API снаружи вообще должно быть до лампочки до начинки.
                                        +1
                                        «Внутри метода» для меня начинается со знака { в Си-подобных языках. И мя параметра это интерфейс прежде всего, даже если он средой исполнения никак не контролируется. Если возникла необходимость переименовать реализацию, то просто сделайте первой строкой в теле метода $new_name = $old_name. А вот изменение имени параметра (части интерфейса) должно свидетельствовать об изменении поведения.
                                          +1
                                          Всё, что внутри метода относится к внутренней реализации и внешний код не должно волновать как называется параметр функции — $cnt или $totalPages.

                                          Это кто вам такое сказал? Есть куча языков и фреймворков, которые подтверждают ошибочность ваших слов.
                                            0
                                            А причём тут «куча языков»? Мы же про PHP говорим.

                                            И потом, отнюдь не куча. В большинстве языков имеет значение именно порядок параметров и/или их тип. Но никак не названия.
                                              +1
                                              Это дефект by design :)
                                +1
                                В случае переименования функции тоже придётся переписывать код.
                                И вариант с именованными параметрами куда удобнее чем передавать массив типа $options, у которого неизвестно какие ключи.
                                Если переменные назвать сразу правильно и к месту, то переименовывать не придётся, а если и возникнет вдруг такая необходимость, то в нормальных средах есть рефакторинг кода.

                                Я только за введение именованных параметров:)
                                  0
                                  > И вариант с именованными параметрами куда удобнее чем передавать массив типа $options, у которого неизвестно какие ключи.

                                  В качестве ключей можно использовать константы класса (многословно, да). Да и потом, тут многие пишут «20 параметров слишком много», какой смысл этой «фичи» при 4-5 параметрах? Никакого.

                                  А насчет рефакторинга — не все IDE его поддерживают (привет PDT), к сожадению. Да и изменить только название метода гораздо быстрее и проще чем проверять и изменять еще и его аргументы (имена которых, ИМХО, вообще относятся к внутренней реализации метода и не должны никаким образом влиять на вызывающий код).
                                    0
                                    Вопрос только в том, что считать сигнатурой, то есть интерфейсом функции/метода.
                                  0
                                  Возможен компромисс вида:
                                  create_query("deleted=0", "name", $report_errors=>false)

                                  Как некое подобие передачи через массив
                                  create_query("deleted=0", "name", array($report_errors=>false))
                                  или
                                  create_query("deleted=0", "name", [$report_errors=>false])
                                    0
                                    Через массив вообще не вариант, как тогда массив передавать?
                                      0
                                      Через массив было бы уместно опять же со спец-синтаксисом — как в Python'е или других языках — через ** или ему подобное. Но поскольку всё упирается в шаманство с парсером — вряд ли мы увидим оптимальные варианты…
                                    +1
                                    Точно так же сейчас можно сказать, что если поменять порядок аргументов функции, то весь тоже придётся переписывать.
                                  +9
                                  А я предложил бы просто ставить запятые без параметров:
                                  create_query("deleted=0", "name", , , false);
                                  

                                  Таким образом работает, например, цикл for. Сразу видно, сколько параметров, в каком порядке идут, и при рефакторинге если сменится имя входящего параметра функции — не будет никаких проблем.
                                    –1
                                    Ваш вариант лучше предложенного, но тоже ужасен. Не должно быть методов с 20-ю аргументами, потому что такой код невозможно читать, не вызывая справку на каждой строчке.
                                      0
                                      Но что если такая функция уже есть, как встроенная?
                                        0
                                        Легче когда передаётся один-единственный массив, ключи которого вообще никак (средствами языка, и даже сторонними типа phpdoc) не документируются? Легче вместо «лезть в справку» (а хорошая IDE подсветит сигнатуру автоматом) лезть в тело и полностью его анализировать?
                                        +1
                                        Мне тоже кажется это самым логичным синтаксисом. Очень давно такого не хватало.

                                        Когда-то давно, когда первый раз возникла необходимость оставить не_последний параметр в значении по-умолчанию, я именно такой синтаксис и использовал. И убедился, что он не работает :)
                                          0
                                          Сможете закинуть с рассылку internals?
                                            0
                                            отличная мысль, гораздо лучше default, тем более, что в list() такое уже используется

                                            –3
                                            На сколько я знаю, сейчас это можно сделать просто указав значение пропускаемого параметра, как NULL, и оно примет значение по умолчанию:
                                            create_query("deleted=0", "name", NULL, NULL, false);
                                            
                                              0
                                              Если в функции это реализовано вручную, то да. А так нет.

                                              function some($arg1, $arg2 = 'some', $arg3 = 5)
                                                  {
                                                  echo $arg1 . ' ' . gettype($arg1) . PHP_EOL; // 1.1 double
                                                  echo $arg2 . ' ' . gettype($arg2) . PHP_EOL; // NULL
                                                  echo $arg3 . ' ' . gettype($arg3) . PHP_EOL; // 100 integer
                                                  }
                                              some(1.1, null, 100);
                                              
                                                0
                                                точно так
                                                • UFO just landed and posted this here
                                                    0
                                                    Можно, но в 99.9999% не нужно.
                                                    Reflection — очень, очень медленно в runtime. Уж лучше программист разок оторвет глазки и посмотрит документацию.
                                                    • UFO just landed and posted this here
                                                  +1
                                                  Хотя нет, я не прав, я внутри уже сам обрабатывал эти NULL, и преобразовывал в значения по умолчанию. Сорри а дезинформацию.
                                                    0
                                                    Нельзя — в метод будет передан null, а не значение по умолчанию.
                                                    +1
                                                    Тоже хочу именованные аргументы…
                                                    • UFO just landed and posted this here
                                                      +2
                                                      А в VB это пишется так:
                                                      create_query("deleted=0", "name", , , false)
                                                      

                                                      Но полагаю, что это не самый хороший вариант, так как можно случайно пропустить какойто параметр, а парсер на это даже ничего не скажет.
                                                        –1
                                                        Давно мечтаю о таком варианте. А что бы ничего не пропускать, надо юзать IDE — они все это умеют.
                                                          0
                                                          Один комментарий не дочитал до вашего, выше написал такой же код)
                                                          0
                                                          Отуствие аннотаций в списке свидетельствует о том, что язык развивается сам по себе, а приложения пишутся сами по себе. Впрочем, как по мне, тут вина не столько разработчиков языка, сколько фреймворков предлагающих их использовать.

                                                          Понравились getters, setters, генераторы (привет руби) и FooBar::class (привет он же).

                                                          Но чего реально нет, каких-то нормальных механизмов задавать конфигурацию на PHP. Массвы себя изжили, а аннотации (в нынешнем виде) не могут быть отлажены никак кроме как в реалтайме.
                                                            +9
                                                            И чем же массивы себя изжили? Не модно?
                                                              –3
                                                              Тем же чем и аннотации — отуствие валидации. Т.е. правильность конфигурации не проверишь пока не запустишь приложение. Тем более не узнаешь, что неправильно написал конфигурацию кеша, пока твой сайт не упал под хабраэффектом.

                                                              Т.е. грубо говоря, хотелось, чтобы можно было задавать конфигурацию в соответствии со схемой.
                                                              И я не говорю, про XML. Я говорю, что сам язык должен иметь средства для задания такого рода конфигураций. Chained methods — как вариант. Но аннотации с интерфейсами были бы лучше.

                                                              И массивы изжили, да.
                                                                +6
                                                                По мне лучший формат — YAML.
                                                                  –2
                                                                  То есть, вместо того, что бы написать над классом, что у поля name должна быть минимальная и максимальная длинна, оно не может быть null, лучше создать еще один файл с описанием классов, полей и какие методы валидации использовать.

                                                                  yaml хорош, но аннотации — это нечто другое. Это мегаудобная метаинформация которую я могу получить в райнайме у объекта без лишних проблем.
                                                                    +5
                                                                    После года на симфони2 я ненавижу аннотации. Они мешают читать код.
                                                                      +2
                                                                      Приведите пример мешающих читать код аннотаций.
                                                                        0
                                                                        У меня дискомфорт когда у свойства 8 строчек комментариев. А свойств бывает более 10. 100 строчек на свойства — излишек.
                                                                          –1
                                                                          А когда эти свойства разнесены по нескольким разным файлам у вас дискомфорта видимо нет?
                                                                            +4
                                                                            Нет. Гармония.
                                                                              +4
                                                                              Мы, в яве, это пережили, несколько лет назад. На людей любящих xml, в котором раньше любой чих любили описывать и которого иногда было больше нежели самого кода, теперь смотрят косо.
                                                                                0
                                                                                YAML не XML. Гораздо проще и понятнее.
                                                                                  +2
                                                                                  Да какая разница, хоть json/bson, хоть любимый бинарный формат.
                                                                                  Это не читаемо, потому что:
                                                                                  1. это лежит хрен знает где.
                                                                                  2. это лежит хрен знает где в хрен знает каком формате.
                                                                                  3. этот формат хреново описан и хреново поддерживается (если конечно не промышленный стандарт, но там другая пичалька)
                                                                                  4. это далеко от того места где я пишу код (иде мне не подскажет где я не прав) а с аннотациями — на раз
                                                                                  5. этих хреней может быть много
                                                                                    0
                                                                                    Если на уровне синтаксиса:
                                                                                    — определить где лежит (autoload)
                                                                                    — определить формат
                                                                                    — нормально документировать
                                                                                    — IDE будет понимать
                                                                                    -оставить единственное место

                                                                                    то у вас претензий не будет?
                                                                                    –2
                                                                                    Ну и yaml нельзя валидировать по схеме. В этом XML выигрывает. Но он менее читабелен, это факт.
                                                                                      +1
                                                                                      Кто запрещает мне валидировать yaml?
                                                                                        0
                                                                                        Отсутствие стандартной возможности задать схему валидации, кроме как соответствие синтаксису?
                                                                                  +3
                                                                                  В мире EE из одной крайности в другую бросаются. Если вспомнить XML-ки того-же Hibernate, то они до занудства «правильные» и жутко избыточные. Впрочем, как и сам XML. С аннотациями, кстати, сильно лучше не стало (по крайней мере пока я ещё в теме был) потому как во-первых чтобы посмотреть на общую картину нужно было лезть в определённые классы, а во-вторых, конфиг, хоть и в аннотациях был не менее монстроподобным.
                                                                                    +2
                                                                                    Да при любом раскладе лучше не станет, таков мир EE. Он странный, надутый и немного пугающий, сам по себе: смешно выглядит прописывание запросов на несколько строчек в аннотациях в качестве оптимизации запросов которые генерит ORM.

                                                                                    Общую картину на пару десятков (а то и сотен) сущностей думаю вряд-ли можно чем-нибудь посмотреть. Иногда даже схемы не спасение.
                                                                              0
                                                                              Вот собственно и пример того, что ни аннотации ни ямл не могут быть идеальным форматом конфигурации.
                                                                          –1
                                                                          По мне так лучше задать этому полю value тип со всеми этими ограничениями. Возможно тип типа generic: IntegerInRange<1,5> вместо типа SchoolMark, описываемого отдельно.
                                                                        +3
                                                                        Вообще-то что аннотации, что XML, что yaml — одно. Если вы не опишите правила по которым нужно валидировать конфигурацию, ничего валидироваться и не будет и, естественно, аннотации никаким боком не спасут ваше приложение от нагрузок, если вы в них прописали медленный бэкенд для кеша. Ровно как и массивы или yaml. Всё это — обёртка и к валидации отношения никакого не имеет.
                                                                          0
                                                                          Думаю тут под валидацией имелось в виду другое. Я думаю если бы можно было бы написать валидатор, который смог понимать при какой нагрузке что как использовать и пинал разработчика, то мы бы жили немного в другом мире.

                                                                          Аннотация она часть кода — ее можно посмотреть, если поле объявлено как int, то туда не получиться запихнуть строку, а вот в конфиге yaml или xml — без правил пожалуйста, а проблема всплывет уже в рантайме.
                                                                            0
                                                                            если поле объявлено как int, то туда не получиться запихнуть строку,

                                                                            Это называется статическая типизация, а не аннотации. Афаик, аннотации это не указания транслятору, это метаинформация для других частей проекта, которая корректно валидироваться может только в рантайме, по крайней мере для интерпретируемых языков со слабой типизацией, каковым является PHP.
                                                                      +4
                                                                      Ну генераторы только в руби есть конечно же.
                                                                    • UFO just landed and posted this here
                                                                        +4
                                                                          +5
                                                                          Асясяй? Какие грабли со свойствами в c#?
                                                                            +5
                                                                            Какие грабли? В шарпе свойства реализованы офигительно. Отдельные уровни доступа, полиморфизм, вынесение в интерфейсы — всё есть.

                                                                            Остальное — это уже культура программирования. Например, свойства при чтении должны возвращать только что записанное. Не быть тяжеловесными. Ну, то есть быть свойствами.
                                                                              0
                                                                              inteface ISample {
                                                                              int Prop {get; set;}
                                                                              int ReadOnlyProp {get;}
                                                                              }

                                                                              Свойства в c# это вообще образец удобства синтаксиса описания свойств. Жаль что в Java/AS3 «пошли своим путем». А в PHP я magic __get/__set принципиально не использую, хотя иногда проперти бы и пригодились, но проще уж через get/set методы, они хоть в автокомплите нормально всплывают. Лично я очень раз что в PHP потянули именно такой синтаксис свойств. Запилят — сразу начну использовать.
                                                                                +1
                                                                                О, поколение, не видевшее Делфи…
                                                                                +3
                                                                                Очень обрадует наличие Простого API для хеширования пароля
                                                                                  +1
                                                                                  Не совсем понятно, как с солью? Это просто надежнее хеш без соли так? Тогда можно было еще параметр влепить для соли.
                                                                                    0
                                                                                    Соль, как я понял, автоматически добавляется. возможно, будет и отдельный метод для её генерации.
                                                                                      +1
                                                                                      А чем конкатенация не угодила?
                                                                                        +1
                                                                                        Влепили:

                                                                                        password_hash(string $password, int $algo, array $options = array()) — … The $options array allows for passing in algorithm specific options. In the case of bcrypt, two options are supported: salt and cost. The salt parameter, if provided, will be used in place of an auto-generated salt
                                                                                          +1
                                                                                          auto-generated salt от чего зависит? Портируема ли между хостами?
                                                                                      0
                                                                                      По поводу пропуска параметров согласен, не удачный вариант.

                                                                                      Я бы предложил нечто такое:
                                                                                      function create_query($where, $order_by, $join_type='', $execute = false, $report_errors = true) {… }
                                                                                      И вызов:
                                                                                      $query = create_query('is_active=1', *5 = false);
                                                                                      Где любая конструкция начинающая с *[1, ...] будет расцениваться как не явный аргумент функции и интерпретироваться уже после того, как все аргументы проставлены.
                                                                                      Например:
                                                                                      $query = create_query('is_active=1', 'name ASC', *2 = 'country DESC');
                                                                                      Таким образом *2 = 'country DESC' оверайдит уже заданный второй аргумент 'name ASC'.
                                                                                        0
                                                                                        Извиняюсь, тэги не подцепились.
                                                                                          +1
                                                                                          Лучше уж тогда именованные, чтобы было видно, что присваиваешь. А так не только нужно порядок помнить, но и рефакторить невозможно простым поиском имени по файлам.
                                                                                            0
                                                                                            Да, в ваших словах есть истина. Я сначала предложил, а только, потом, подумал :-)
                                                                                            Спасибо за критику.
                                                                                          –1
                                                                                          > предложение новой функции array_column
                                                                                          И ведь запихают в глобальное пространство имен, и старый код с аналогичными пользовательскими функциями работать не будет на новых версиях PHP.
                                                                                            +2
                                                                                            Эм… if(!function_exists('array_column')){ function array_column(…){…}} не?
                                                                                              0
                                                                                              Вы не поняли, к чему я это сказал.
                                                                                              Код мог быть написан до появления 5.3 с неймспейсами.
                                                                                              И содержать эту функцию. Или другую функцию, или класс.
                                                                                              И реализация наверняка бы отличалась. Ну, к примеру, другим порядком параметров. Или вовсе делало абсолютно другое.

                                                                                              Т.е. я считаю, что захламлять глобальное пространство имен — плохая идея.
                                                                                                +5
                                                                                                Учитывая существование пространств имён, если программист использует глобальное пространство — то он ССЗБ.

                                                                                                В древний код можно добавить пространства. Никто никогда не обещал 100%-ной обратной совместимости.
                                                                                                  –1
                                                                                                  Почему вы делаете нападки на программистов, пространства не использующих(к примеру потому, что их не было, когда писался код), но не на разработчиков PHP?

                                                                                                  Как по мне, то это равнозначный косяк и для тех, и для других.
                                                                                                    0
                                                                                                    Ваше решение проблемы? Не добавлять новые функции? Добавлять в пространство имён PHP_internal_do_no_use? :)
                                                                                                      0
                                                                                                      Мое решение проблемы — strict режим, выключенный по умолчанию.
                                                                                                      Выключенный по умолчанию для целей обратной совместимости.
                                                                                                      При этом хотелось бы видеть функции для строк/массивов не просто перемещеными в неймспейс, а нормальыми полноценными методами строк. Типа " foo ".trim()
                                                                                                        0
                                                                                                        Представьте себе, именно так:
                                                                                                        Note:

                                                                                                        Namespace names PHP and php, and compound names starting with these names (like PHP\Classes) are reserved for internal language use and should not be used in the userspace code.

                                                                                                        Мануал по пространствам имен на php.net
                                                                                                          0
                                                                                                          Reserved but not used :(
                                                                                                          0
                                                                                                          Как минимум разнести старые функции стандартной библиотеки по пространствам имён \PHP\… с соответствующим переименованием (вместо \array_merge \PHP\Array\merge), объявив старые depricated aliases. Это позволило бы к следующей (6.0?) версии избавиться от унаследованного именования вообще.
                                                                                                +13
                                                                                                Looks like Python.
                                                                                                  +2
                                                                                                  Та же мысль пришла в голову. Но лучше с PHP, чем без него, конкуренция — это всегда хорошо :)
                                                                                                    +4
                                                                                                    У слона растёт змеиный хвост.
                                                                                                      –1
                                                                                                      И рубиновый хобот :) Няшка :)
                                                                                                        0
                                                                                                        Или откуда-то торчит коллектив шоу Монти Пайтона? :)
                                                                                                      +3
                                                                                                      Вам default и куча аргументов не нравится? Как же интересно должна выглядеть createThumbnail($source, $destination, $cropX1, $cropY1, $cropX2, $cropY2, $backgroundColor, $quality, $forceRegenerate)?

                                                                                                      Я не пойму, кому может нравиться такое:
                                                                                                          public $hours {
                                                                                                              get { return $this->seconds / 3600; }
                                                                                                              set { $this->seconds = $value * 3600; }
                                                                                                          }
                                                                                                      

                                                                                                      Как скажите в наследнике переопределять эти вещи? parent::set($value) что-ли? И нормально ли будет дебажить тормоза, когда $this->hour = 5, делает меняет не только $hour (да и вообще вдруг тормозит). Это же функция с побочным эффектом, но завуалированная под аттрибут.
                                                                                                        +8
                                                                                                        <?php
                                                                                                        
                                                                                                        $imagine = new Imagine\Gd\Imagine();
                                                                                                        // or
                                                                                                        $imagine = new Imagine\Imagick\Imagine();
                                                                                                        // or
                                                                                                        $imagine = new Imagine\Gmagick\Imagine();
                                                                                                        
                                                                                                        $size    = new Imagine\Image\Box(40, 40);
                                                                                                        
                                                                                                        $mode    = Imagine\Image\ImageInterface::THUMBNAIL_INSET;
                                                                                                        // or
                                                                                                        $mode    = Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND;
                                                                                                        
                                                                                                        $imagine->open('/path/to/large_image.jpg')
                                                                                                            ->thumbnail($size, $mode)
                                                                                                            ->save('/path/to/thumbnail.png')
                                                                                                        ;
                                                                                                        


                                                                                                        github.com/avalanche123/Imagine/
                                                                                                          0
                                                                                                          Неплохо :)
                                                                                                            0
                                                                                                            Спасибо, беру.
                                                                                                            0
                                                                                                            Предложенный вариант, как было замечено выше, очень походит на зачатки реализации свойств в C#. Но в нем есть модификатор new, который позволяет заменить родительское свойство, а к замененному обращаться через приведение типов.

                                                                                                            Переопределять в предложенном варианте PHP, полагаю, так:

                                                                                                            public $hours {
                                                                                                                get { return parent::$hours; }
                                                                                                                set { parent::$hours = $value; }
                                                                                                            }
                                                                                                            
                                                                                                              0
                                                                                                              ClassName::$varName уже для переменных переменных используется.
                                                                                                                0
                                                                                                                Вы, наверное, имели в виду, для статических переменных. Да, вы правы, забыл о них. Тогда как в C#:

                                                                                                                public $hours {
                                                                                                                    get { return ((parent)$this)->hours; }
                                                                                                                    set { ((parent)$this)->$hours = $value; }
                                                                                                                }
                                                                                                                
                                                                                                                  0
                                                                                                                  В set, конечно, без $ (опечатался)

                                                                                                                  ((parent)$this)->hours = $value;
                                                                                                                  
                                                                                                              +2
                                                                                                              Не все так плохо.

                                                                                                              public $hours = {
                                                                                                                  get { inherit; }
                                                                                                                  set { /* Set value here ... */ }
                                                                                                              }
                                                                                                              
                                                                                                              –6
                                                                                                              Для меня пока что самое ожидаемое нововведение — это когда к объектам можно будет обращаться через точку "."
                                                                                                                +7
                                                                                                                Ради субъективной читабельности что-ли, так скорее как в Scala -> будет автозаменяться на → в IDEшках, а язык будет поддерживать и то и другое. А точка уже закреплена за конкатенацией, так что не дождетесь :)
                                                                                                                  +2
                                                                                                                  Никогда, наверное. Иначе как отличить от конкатенации?
                                                                                                                    –1
                                                                                                                    Заменить конкатенацию. на +? :)
                                                                                                                      0
                                                                                                                      «1» + «1»?
                                                                                                                        0
                                                                                                                        Для PHP это не проблема :)
                                                                                                                          0
                                                                                                                          В смысле ещё одно «это невозможно понять, это нужно запомнить».
                                                                                                                            +1
                                                                                                                            Так что должно получиться «11» или 2?
                                                                                                                              –3
                                                                                                                              Что напишут в мануле, то и будет должно. Для избежания разрыва шаблона скорее «11» как в JavaScript. Оба операнда строковые и нет никакого смысла их приводить ещё к чему-то.
                                                                                                                                +2
                                                                                                                                То есть все, что было написано ранее перестанет работать?
                                                                                                                                  –2
                                                                                                                                  В 5.5. depricated сделать где используется точка для конкатенации и плюс для сложения двух строк…
                                                                                                                                    +1
                                                                                                                                    И на 5.6 никто не перейдёт.

                                                                                                                                    Как на python 3.

                                                                                                                                    Вам оно надо?
                                                                                                                                      –2
                                                                                                                                      Я перейду, хостинги будут, пускай и не по дефолту, а из панели/по заявке.
                                                                                                                      +1
                                                                                                                      И какого результата вы ожидаете от кода?
                                                                                                                      const b = 'bar';
                                                                                                                      class A {
                                                                                                                          public $b = 'baz';
                                                                                                                          function __toString() {
                                                                                                                              return 'foo';
                                                                                                                          }
                                                                                                                      }
                                                                                                                      echo new A().b;
                                                                                                                        0
                                                                                                                        Согласен, что не получится. Я лишь в теории высказался, т.к точку-конкатенацию никто не станет переделывать на "+". Javascript в этом плане удобен, но некоторые операции с "+" порой имеют непредсказуемые результат, если не знать некоторых тонкостей.
                                                                                                                      –14
                                                                                                                      Капитан php стал еще могущественнее!
                                                                                                                      itmages.ru/image/view/585443/11cf38f0
                                                                                                                        +13
                                                                                                                        Дружище, ты в каждый пост о php будешь копипастить этого капитана? Понравилось карму поднимать?
                                                                                                                          0
                                                                                                                          Похоже это был последний раз. И я, в виду такого случая, даже глянул что же это за «Капитан PHP»
                                                                                                                        +7
                                                                                                                        Отказ от поддержки Windows XP и 2003

                                                                                                                        Мне-то пофиг, конечно, но интересно, что такого есть в семёрке, чего нет в хрюшке, что требует ощутимой работы по поддержке.

                                                                                                                        Получение полного имени класса

                                                                                                                        Ещё бы они получение имени функции сделали, чтобы не было «указателей на функцию» в виде array('Foo', 'bar'), которые IDE не могут валидировать. Хочу array(Foo::class, Foo::bar) или что-нибудь вроде того.

                                                                                                                        Пропуск параметров

                                                                                                                        Этим ужасом никто пользоваться не будет. Что это за синтаксический сахар, если используется длиннющее «default»? Сделали бы именованное обращение к аргументам при вызове функции, если уж так хочется поддерживать говнокодерство с методами на 20 аргументов.

                                                                                                                        Контроль типа для скалярных значений

                                                                                                                        Наконец-то они одумались! Нужна не строгая проверка на тип, а приведение.

                                                                                                                        Getters и setters

                                                                                                                        Наконец-то! Ненавижу, когда ради обращения к свойству приходится производить кучу операций на строках — курам на смех.

                                                                                                                        Генераторы
                                                                                                                        Выделение списков и выражения-генераторы

                                                                                                                        Звучит офигительно! Хочу. Особенно учитывая, какой кошмарный код приходится писать для реализации LINQ в PHP — при использовании ленивых вычислений код становится трудно читаемым.
                                                                                                                          –1
                                                                                                                          Этим ужасом никто пользоваться не будет… если уж так хочется поддерживать говнокодерство с методами на 20 аргументов

                                                                                                                          Ошибаетесь. И я еще жду ответа на вопрос как разговнокодить createThumbnail($source, $destination, $cropX1, $cropY1, $cropX2, $cropY2, $backgroundColor, $quality, $forceRegenerate)
                                                                                                                            –1
                                                                                                                            > И я еще жду ответа на вопрос как разговнокодить createThumbnail

                                                                                                                            В идеально мире: создать класс Thumbnail, в конструктор передавать $source, также добавить в него методы для установки всех свойств (setCrop и т.д.) и потом вызывать create($destination).
                                                                                                                              +2
                                                                                                                              также добавить в него методы для установки всех свойств

                                                                                                                              Фигня это, а не идеальный мир, имхо. Нафига писать 7 вызовов set* и в конце 1 create вместо того чтобы вызвать create с 8 параметрами? И, кстати, а чего для desination отдельного set не предусмотрели?
                                                                                                                                –2
                                                                                                                                > Нафига писать 7 вызовов set* и в конце 1 create вместо того чтобы вызвать create с 8 параметрами?

                                                                                                                                Ниже ashofthedream почти тоже самое написал, но если вам непонятно в виде слов, то вот код:

                                                                                                                                $thumb = new Thumbnail($source).

                                                                                                                                $thumb->setCrop($cropX1, $cropY1, $cropX2, $cropY2);
                                                                                                                                $thumb->setBackgroundColor($backgroundColor);
                                                                                                                                $thumb->setQuality($quality);

                                                                                                                                $create = $thumb->create($destination, $forceRegenerate);

                                                                                                                                if (!$create) {
                                                                                                                                // bla bla bla
                                                                                                                                }

                                                                                                                                Непонятно где вы тут семь сеттеров насчитали. На последний вопрос думаю не нужно отвечать?
                                                                                                                                  +2
                                                                                                                                  Мне сложно оценить семантику, но почему не setCropAndBackgroundColor? И что будет если не задать Crop или Quality? Имхо, сеттерами можно либо задавать необязательные параметры, либо изменять установленные конструктором 9в особых случаях рефлексией). Но если математической формуле требуется 8 параметров, то и нужно ей передать 8 параметров. В крайнейм случае сгруппировав их в объекты/массивы, то есть код должен быть типа такого:

                                                                                                                                  $crop = new Crop($cropX1, $cropY1, $cropX2, $cropY2);
                                                                                                                                  $thumb = new Thumbnail($source, $crop, $backgroundColor);
                                                                                                                                  $create = $thumb->create($destination, $forceRegenerate);
                                                                                                                                  
                                                                                                                                  if (!$create) {
                                                                                                                                  // bla bla bla
                                                                                                                                  }
                                                                                                                                  

                                                                                                                                  Причём $crop введена лишь для удобства чтения, можно было её вставить new Crop($cropX1, $cropY1, $cropX2, $cropY2); в конструктор Thumbnail непосредственно.
                                                                                                                                    –1
                                                                                                                                    > Мне сложно оценить семантику, но почему не setCropAndBackgroundColor?

                                                                                                                                    Потому что мне так удобнее :) Если что-то не указано, то будут использованы параметры по умолчанию, которые в *моей* реализации имеют подходящие для моего случая значения.

                                                                                                                                    > $crop = new Crop($cropX1, $cropY1, $cropX2, $cropY2);

                                                                                                                                    Если Crop используется только для хранения четырех значений, то он, ИМХО, лишний и лучше просто передать их в метод.

                                                                                                                                    > $thumb = new Thumbnail($source, $crop, $backgroundColor);

                                                                                                                                    Это практически ничем не отличатся от такого:

                                                                                                                                    $thumb->setCrop($crop);
                                                                                                                                    $thumb->setBackgroundColor($backgroundColor);

                                                                                                                                    Все зависит от личных предпочтений разработчика, кому то вон цепочки нравятся :)
                                                                                                                                      0
                                                                                                                                      Потому что мне так удобнее :)

                                                                                                                                      Вопросов больше нет :(
                                                                                                                                        0
                                                                                                                                        > Вопросов больше нет :(

                                                                                                                                        А что вы хотели услышать? Что не логично (как минимум) изменять совершенно разные по смыслу свойства через один метод? Ну, так, это вроде и так всем известно. Смысл повторяться?

                                                                                                                                        С тем что «каждый в итоге пишет именно так как ему удобнее в конкретном проекте» (например, вам все сразу передать в конструкторов, мне — изменить позже через сеттеры) спорить не будете? Поэтому нет никакого смысла обсуждать обычные пять строк кода, тем более, что он полностью отвечает на изначально заданный вопрос (хотя и он сам по себе излишен — все написано в первом комментарии).
                                                                                                                                          0
                                                                                                                                          Думал, что объясните необходимость иметь возможность изменять свойства одноразового по сути объекта.
                                                                                                                                            0
                                                                                                                                            Тогда и надо было спрашивать об этом (в вашем комментарии совсем другие вопросы написаны).

                                                                                                                                            Кстати, а ваш вариант разговнокодивания какой?
                                                                                                                              +7
                                                                                                                              Просто очень разговнокодить, достаточно сделать из вызова одного метода некий билдер.
                                                                                                                              Thumbnail.from(source)
                                                                                                                              .crop(100, 100) 
                                                                                                                              .quality(3)
                                                                                                                              .forceRegenerate(true)
                                                                                                                              .blabla(somearg)
                                                                                                                              .create(destination);
                                                                                                                              


                                                                                                                                +3
                                                                                                                                Функция не обязательно должна иметь много параметров, что бы захотеть их пропустить:
                                                                                                                                html_entity_decode( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = 'UTF-8' ]] )
                                                                                                                                

                                                                                                                                3 параметра, 2 из которых не обязательны — это много или мало?
                                                                                                                                htmlspecialchars(<4 параметра>) — это кривая функция?
                                                                                                                                  –1
                                                                                                                                  Что htmlspecialchars, что html_entity_decode — не совсем красивые (да, тут наверное можно упомянуть слово кривые) функции, по хорошему они должны выглядеть так:
                                                                                                                                  html_entity_decode( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = 'UTF-8' ]] )
                                                                                                                                  html_entity_decode( string $string [, string $encoding = 'UTF-8' ] )
                                                                                                                                  html_entity_decode( string $string [, int $flags = ENT_COMPAT | ENT_HTML401])
                                                                                                                                  


                                                                                                                                  htmlspecialchars разбивается так же, ну вот не нужно мне указывать какие-то там флаги, зачем мне писать их, если я хочу указать кодировку? Правильно — незачем.

                                                                                                                                  Но, к сожалению, дизайн языка не позволяет делать function overloading и поэтому мы имеем то, что имеем
                                                                                                                                    0
                                                                                                                                    зачем мне писать их, если я хочу указать кодировку?

                                                                                                                                    Ну так не пишите:
                                                                                                                                    html_entity_decode($string, , 'UTF-8'); // Отличный, удобный вариант.
                                                                                                                                    // Это универсальнее, проще и понятнее чем function overloading.
                                                                                                                                    
                                                                                                                                      0
                                                                                                                                      Неудобно когда надо еще условие, например:
                                                                                                                                      html_entity_decode($string, empty($param) ? default : $param, 'UTF-8');
                                                                                                                                      
                                                                                                                                        0
                                                                                                                                        В таком исключительном случае, вы можете передать дефолтное значение
                                                                                                                                        html_entity_decode($string, empty($param) ? (ENT_COMPAT | ENT_HTML401) : $param, 'UTF-8');
                                                                                                                                        

                                                                                                                                        Но:
                                                                                                                                        1. такое приходится писать крайне редко. И ради 1% случаев заставлять писать себя «default» во всех остальных 99% случаев как то не гуманно. Мне в 100500 раз проще написать "" чем «default».

                                                                                                                                        2. Я бы вообще не использовал тернарные условия внутри других длинных выражений. Тернарники и без того имеют сложно-читаемый синтаксис, по этому я бы разнёс на две строки:
                                                                                                                                        $flags = empty($param) ? (ENT_COMPAT | ENT_HTML401) : $param;
                                                                                                                                        html_entity_decode($string, $flags, 'UTF-8');
                                                                                                                                        


                                                                                                                                        3.!!! САМЫЙ ГЛАВНЫЙ ДОВОД!!! Предложенный вами синтаксис не локаничен! Например, я не могу разбить его на 2 строки:
                                                                                                                                        $flags = empty($param) ? default : $param; // что здесь обозначает default ???
                                                                                                                                        html_entity_decode($string, $flags, 'UTF-8');
                                                                                                                                        


                                                                                                                                        4. define('default', 'custom'); // Что произойдёт? Или теперь нельзя создавать константу с именем 'default'? Ох, сколько же ещё зарезирвированных слов придумают изобретатели php и как все эти слова запомнить?
                                                                                                                                          +1
                                                                                                                                          По поводу (4) — скорее всего да, думаю будет зарезервированное слово, как null, true, false. И тогда конечно будет работать и (3) пункт (самый главный довод).
                                                                                                                                          По поводу тернарных (2) — оффтопик, конечно лучше на другой строке, а вообще всё индивидуально.
                                                                                                                                          Касательно (1) — писать default в 99% случаях — на это есть питоновский дзен — «Явное лучше, чем неявное».
                                                                                                                                            0
                                                                                                                                            По поводу (4): зачем ещё одно зарезервированное, если можно без него? Как же питоновский дзен? Представьте себе сколько появится вопросов на форумах от пхп-джуниров: «что такое default?».

                                                                                                                                            Самый главный пункт №3 работать НЕ будет, потому что придётся ещё вводить новый специальный тип значений. «тип значение» != «зарезервированному слову». Иначе, представляете такой код:
                                                                                                                                            $flags = empty($param) ? default : $param;
                                                                                                                                            var_dump($flags); // что здесь будет?
                                                                                                                                            


                                                                                                                                            По поводу №1. Это гораздо нагляднее:
                                                                                                                                            html_entity_decode($string, , 'UTF-8');
                                                                                                                                            

                                                                                                                                            чем это:
                                                                                                                                            html_entity_decode($string, default, 'UTF-8');
                                                                                                                                            

                                                                                                                                            В первом случае всё чётко и понятно: параметр не указан! Даже джуниоры не будут задавать вопросы на форумах — всё чётко и понятно!

                                                                                                                                            Во втором случае надо ВЧИТАТЬСЯ и ОСМЫСЛИТЬ, вспомнить зарезервированное слово default, не перепутать его с null и константой defence :). Возможно у питонщиков это уже вшито в мозг с рождения, но у нас пэхапэшников пока нет.
                                                                                                                                              +4
                                                                                                                                              зачем ещё одно зарезервированное, если можно без него?

                                                                                                                                              Оно уже зарезервировано для использования в switch..case..default. Так что нового зарезервированного слова не появляется.

                                                                                                                                                +1
                                                                                                                                                точно точно! вы правы!

                                                                                                                                                есть питоновский дзен — «Явное лучше, чем неявное». 
                                                                                                                                                

                                                                                                                                                html_entity_decode($string, , 'UTF-8');
                                                                                                                                                

                                                                                                                                                Я пропустил параметр. Что может быть более явным обозначением пропущенного параметра?

                                                                                                                                                А ещё я представляю себе две строчки в документации:
                                                                                                                                                Что бы пропустить не обязательный параметр, пропустите этот параметр
                                                                                                                                                // vs
                                                                                                                                                Что бы пропустить не обязательный параметр, укажите специальную конструкцию языка "default"
                                                                                                                                                А почему не empty?

                                                                                                                                                Ну и ещё один питоновский дзен:
                                                                                                                                                Особые случаи не настолько особые, чтобы нарушать правила.

                                                                                                                                                  0
                                                                                                                                                  это уж вопросы не ко мне, я бы тоже предпочел отсутствие параметра специальному слову — хотя бы для консистентности с list(,$val) = each($arr)
                                                                                                                                                    0
                                                                                                                                                    Я пропустил параметр. Что может быть более явным обозначением пропущенного параметра?

                                                                                                                                                    Зная любовь PHP ко всяким неявным приведениям типов я, имхо, имею полное право считать, что пропуск параметра приведётся к NULL. Никто мне не докажет, что это менее логично, чем принятие значения по умолчанию в сигнатуре функции. Вот default, да, говорит о том, что если не знаешь о чём это, то нужно заглянуть в ман.

                                                                                                                                                    P.S. А константы я бы вообще запретил именовать как-то кроме upper case на уровне синтаксиса.
                                                                                                                                                      +1
                                                                                                                                                      имею полное право считать, что пропуск параметра приведётся к NULL
                                                                                                                                                      

                                                                                                                                                      Не имеете:
                                                                                                                                                      $x = ; // это не работает.
                                                                                                                                                      
                                                                                                                                                      Хотя, если «правильно» посчитать, то можно со спокойной совестью пропускать параметры используя null уже сейчас:
                                                                                                                                                      html_entity_decode($string, null, 'UTF-8');
                                                                                                                                                      
                                                                                                                                                      null — это же ведь «ничто», т.е. я как бы «передал ничто» или «ничего не передал». В оффициальной документации вообще написано, что переменная считается null-ом если она была удалена с помощью unset(). :) Т.е. отстутвующая переменная приравнивается к null.

                                                                                                                                                      Я это всё к тому, что «считалка» не работает и не надо ничего считать Это же php :(

                                                                                                                                                      Это кстати, не единственный приведённый мной аргумент в пользу «пропуска параметра пропуском параметра». Ещё очень важна читабельность (см. 5 комментов выше).

                                                                                                                                                      Ну и мне ещё не охото каждый раз как мартышка печатать «default» там где можно ничего не печатать.

                                                                                                                                                      P.S. я бы тоже этого хотел. И ещё очень хочу что бы все уровни ошибок были включены без возможности отключения, даже NOTICE.
                                                                                                                                                        0
                                                                                                                                                        «передал ничто» ни в коем случае не равно «ничего не передал». Транзакция по счёту на ноль рублей не равна отсутствию транзакции (и даже баланс может измениться при транзакции). Молчание в ответ на вопрос не равно отсутствию того кому вопрос задавать…
                                                                                                                                                          0
                                                                                                                                                          Тогда почему вы считаете что пропущенный параметр можно приравнивать к null?
                                                                                                                                                            0
                                                                                                                                                            Я считаю, что пропущенный параметр это неопределенное поведение — это может быть NULL (логично с одной стороны), это может значение по умолчанию (с другой), а может быть 42 (просто так).
                                                                                                                                                    +1
                                                                                                                                                    Хотя стоп-стоп! Сейчас можно определять константу default!!!

                                                                                                                                                    Я проверил на php 5.3.11:
                                                                                                                                                    define('default', 'custom');
                                                                                                                                                    var_dump('test');
                                                                                                                                                    
                                                                                                                                                    Отлично отрабатывает.

                                                                                                                                                    Правда при попытки её использования вылетает ошибка
                                                                                                                                                    define('default', 'custom');
                                                                                                                                                    var_dump(default); // Parse error: syntax error, unexpected ...
                                                                                                                                                    


                                                                                                                                                    Но дефайнить её никто не запрещал :) Возвращаю свой плюс обратно :)
                                                                                                                                                      0
                                                                                                                                                      Да дефайнить можно что угодно, хоть одинарную кавычку. Использовать потом, правда, неудобно, только через constant();
                                                                                                                                                      define("'", 123);
                                                                                                                                                      var_dump(constant("'")); // 123
                                                                                                                                                      
                                                                                                                                                        0
                                                                                                                                                        Не всё:
                                                                                                                                                        define('true', false); // Notice: Constant true already defined
                                                                                                                                                        
                                                                                                                                                          +1
                                                                                                                                                          Кроме уже определенных констант. Это подразумевалось по умолчанию.
                                                                                                                                                            –1
                                                                                                                                                            Гы.

                                                                                                                                                            var_dump(FALSE);
                                                                                                                                                            // bool(false)
                                                                                                                                                            
                                                                                                                                                            var_dump(TRUE);
                                                                                                                                                            // bool(true)
                                                                                                                                                            
                                                                                                                                                            define('TRUE', false);
                                                                                                                                                            define('FALSE', true);
                                                                                                                                                            
                                                                                                                                                            var_dump(TRUE);
                                                                                                                                                            // bool(false)
                                                                                                                                                            
                                                                                                                                                            var_dump(FALSE);
                                                                                                                                                            // bool(true)

                                                                                                                                                            Это просто жесть :)
                                                                                                                                                              0
                                                                                                                                                              Это вы в какой версии нашли?
                                                                                                                                                                0
                                                                                                                                                                5.3.10
                                                                                                                                                                  0
                                                                                                                                                                  в 5.3.3 и 5.3.6 такого нет. В 5.4.4, насколько помню, тоже.
                                                                                                                                                                    0
                                                                                                                                                                    А в интерактивном режиме (php -a)?
                                                                                                                                                                      0
                                                                                                                                                                      В 5.4 проверить сейчас не могу, но в остальных двух действительно так, как вы говорили. Запостите баг?
                                                                                                                                                                0
                                                                                                                                                                shock@shock-notebook:~$ php -v
                                                                                                                                                                PHP 5.3.10-1ubuntu3.2 with Suhosin-Patch (cli) (built: Jun 13 2012 17:20:55)
                                                                                                                                                                Copyright © 1997-2012 The PHP Group
                                                                                                                                                                Zend Engine v2.3.0, Copyright © 1998-2012 Zend Technologies

                                                                                                                                                                shock@shock-notebook:~$ php define.php
                                                                                                                                                                bool(false)
                                                                                                                                                                bool(true)
                                                                                                                                                                bool(true)
                                                                                                                                                                bool(false)
                                                                                                                                                                  0
                                                                                                                                                                  Интересно. А теперь попробуйте в интерактивном режиме.
                                                                                                                                              0
                                                                                                                                              function overloading по типу параметров для задания параметров по умолчанию — это костыль, имхо. Пропуск параметров, ключевое слово или именованные параметры выглядят куда лучше этого костыля. У них есть свои плюсы и минусы, но любой из них лучше.

                                                                                                                                              Плюс, как вы предлагаете быть с функцией, у которой 3 строковых параметра, два из которых необязательные?
                                                                                                                                          –2
                                                                                                                                          Создать класс CreateThumbnailParams. По вкусу можно добавить в CreateThumbnailParams конструктор, присваивающий значения полям по переданному ассоциативному массиву. Будет так:

                                                                                                                                          createThumbnail($mySource, $myDestination, new CreateThumbnailParams(array('quality' => 10)))
                                                                                                                                          

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

                                                                                                                                          Ну да, с таким конструктором обращение к полям будет через строчки, что в IDE не проверяется. Но IDE можно доработать, в теории.
                                                                                                                                            +1
                                                                                                                                            Превращать опциональные аргументы в массив аргументов — это еще хуже, не формализованно. Сеттеры как у lastdragon и цепочки вызовов ashofthedream, все это еще куда ни шло. Но когда речь идет о, скажем, непубличной функции, то создавать вместо нее класс — имхо как из пушки по воробьям. Иногда функция таки зависит от 20 параметров. Есть что-то интересно в ObjectiveC стиле, вроде createThubnail($cropX1=>10, $forceRegenerate=>true), но наверное и правда неудобно рефакторить.
                                                                                                                                              +3
                                                                                                                                              20 параметров для функции — это слишком много. Что она должна делать то при этом? А так, люди давно эту проблему решили, в корне, например в том же ObjectiveC. В любом языке должна быть такая вещь:
                                                                                                                                              foo.do(bar: "this is the bar", really: true);
                                                                                                                                              

                                                                                                                                              Все, читаемо, понятно, удобно, быстро, красиво.
                                                                                                                                                +1
                                                                                                                                                Согласен, именованные аргументы хорошая штука
                                                                                                                                                  +1
                                                                                                                                                  ну так никто не мешает сделать прямо сейчас в php
                                                                                                                                                  foo.do({ 'bar' => "this is the bar",  'really' => true });
                                                                                                                                                  


                                                                                                                                                    0
                                                                                                                                                    Еще хуже: как я узнаю, не заглянув фунцкию какие аргументы она принимает, какого они должны быть типа, какие обязательные, а какие нет?
                                                                                                                                                      +1
                                                                                                                                                      из описания функции вестимо
                                                                                                                                                        0
                                                                                                                                                        Опять держать открытым мануал? А если это функция напиана Васей который сидит в трех метрах от меня и правлена Петей который сидит за васей, а комменты он подправить забыл?
                                                                                                                                                          –1
                                                                                                                                                          Зачем мануал — phpdoc достаточно и нормальный IDE работает по нему или показывает хотя бы. Вася, Петя… вы бы еще про уборщицу вспомнили, которая в теле изменила бы параметр, а в заголовке нет :)
                                                                                                                                                            –1
                                                                                                                                                            Проблема документации в том, что она очень часто в своих проектах не соответсвует действительности. Да что говорить о документации-то, когда некоторые личности после рефакторинга тесты мьютят потому что лень править и «ну как-нибудь потом»
                                                                                                                                                              +2
                                                                                                                                                              Гнать таких.
                                                                                                                                                                0
                                                                                                                                                                Конечно же я с вами согласен, но в моем случае пришлось самому покинуть такую команду.
                                                                                                                                                              +1
                                                                                                                                                              > вы бы еще про уборщицу вспомнили, которая в теле изменила бы параметр, а в заголовке нет

                                                                                                                                                              А вот запросто, видел кучу кода (да и вот прямо сейчас гляжу на него) в котором в phpdoc вообще нет названий аргументов, только их типы. Поэтому phpdoc, в отличие от автокомплита, можно полноценно использовать только в идеальном мире. Да и от его *устаревания* никто не застрахован.
                                                                                                                                                        0
                                                                                                                                                        Если на уровне синтаксиса будет поддерживаться

                                                                                                                                                        foo.do($bar => "this is the bar",  $really => true );
                                                                                                                                                        


                                                                                                                                                        то это будет лучше для всех, имхо. Разве что любители удалять гланды через ж… будут недовольны.
                                                                                                                                                        0
                                                                                                                                                        > Все, читаемо, понятно, удобно, быстро, красиво.

                                                                                                                                                        И куча проблем при рефакторинге.

                                                                                                                                                        > 20 параметров для функции — это слишком много.

                                                                                                                                                        А при небольшом кол-ве параметров функции эта «фича» совершенно лишняя.
                                                                                                                                                          0
                                                                                                                                                          эта фича совершенно не лишняя, если даже у нас 3-4 параметра для функции, один из которых не обязателен, а другие просто можем испльзовать в различных вариациях. Таких функций в пхп over 9k и часто приходиться пропускать аргументы
                                                                                                                                                            0
                                                                                                                                                            При 3-4 параметрах гораздо быстрее написать default (или ,,) чем вспоминать какой из них как называется (тем более в PHP).
                                                                                                                                                              +1
                                                                                                                                                              Так для таких фич требуется поддержка IDE
                                                                                                                                                          0
                                                                                                                                                          Именованные параметры могут помочь и с повышением читаемости вызова при большом количестве аргументов. Например, возьмем Imagick:
                                                                                                                                                          $im->floodfillpaintimage($iPixel,10,$tPixel,$startX,$startY,false,Imagick::CHANNEL_DEFAULT); // versus $im->floodfillpaintimage({ $fill=>$iPixel, $fuzz=>10, $bordercolor=>$tPixel, $x=>$startX, $y=>$startY, $invert=>false, $CHANNEL=>Imagick::CHANNEL_DEFAULT });
                                                                                                                                                          Такой подход заметно упрощает чтение и рефакторинг в использовании метода, особенно при поддержке IDE.
                                                                                                                                                          Правда остается непонятно, что при этом делать в случае рефакторинга имен параметров в библиотеке, однако мне не кажется это такой большой проблемой: о том, что трудно поменять параметры местами или что-то добавить ведь никто не плачется?
                                                                                                                                                            0
                                                                                                                                                            Черт, никак не запомню как тут правильно код выделять, а предросмотр глючит…
                                                                                                                                                            $im->floodfillpaintimage($iPixel,10,$tPixel,$startX,$startY,false,Imagick::CHANNEL_DEFAULT);
                                                                                                                                                            // versus
                                                                                                                                                            $im->floodfillpaintimage({ 
                                                                                                                                                               $fill=>$iPixel, 
                                                                                                                                                               $fuzz=>10, 
                                                                                                                                                               $bordercolor=>$tPixel, 
                                                                                                                                                               $x=>$startX, 
                                                                                                                                                               $y=>$startY, 
                                                                                                                                                               $invert=>false, 
                                                                                                                                                               $CHANNEL=>Imagick::CHANNEL_DEFAULT }); 
                                                                                                                                                            
                                                                                                                                                              0
                                                                                                                                                              что при этом делать в случае рефакторинга имен параметров в библиотеке

                                                                                                                                                              Это по определению не будет называться рефакторингом, это уже изменение интерфейса со всеми вытекающими…
                                                                                                                                                                0
                                                                                                                                                                Будет. Тут нет изменений в интерфейсе (по крайней мере до тех пор пока нет именованных параметров).
                                                                                                                                                                  0
                                                                                                                                                                  Для меня это уже сейчас изменение интерфейса. Думаете замена метода Stack::popArray($countToPop) на метод Stack::popArray($countToLeave) для клиентов метода не будет означать необходимости изменения логики их обращения к методу? Синтаксически, конечно, не будет, но вот семантически скорее всего потребует, и я бы предпочёл чтобы «компилятор» мне выдал Fatal Error, а не утекла база данных несоленых паролей :)
                                                                                                                                                                    0
                                                                                                                                                                    Конкретно этот пример будет, только у вас же кроме изменения параметра, изменена и логика метода => оставить прежнее название не очень хорошее решение.

                                                                                                                                                                    А вот если было что-то типа b($a, $b), а стало b($start, $length), то нет.
                                                                                                                                                                      0
                                                                                                                                                                      Откуда вы знаете, что она изменена? :) Именование параметров внутренне дело функции же! Захотел и изменил имя параметра без изменения логики, захотел изменил логику без изменения имени параметра. Но мне кажется, что чаще встречаются ситуации когда либо меняется и имена параметров, и логика (мой пример), либо имена функции и ей параметров (доведенный до логического конца ваш пример, например, xrange($start, $length) )
                                                                                                                                                            0
                                                                                                                                                            >Превращать опциональные аргументы в массив аргументов — это еще хуже, не формализованно.

                                                                                                                                                            что с ними не так?
                                                                                                                                                              0
                                                                                                                                                              Хотя бы что нужно постоянно в документацию лазить, чтобы узнать какие параметры есть. Впрочем, это отчасти решается константами класса (CreateThumbnailParams::QUALITY), но получается многословно.
                                                                                                                                                                0
                                                                                                                                                                Интерфейс достаточно описать в описании функции и дока в нормальном IDE будет всегда рядом
                                                                                                                                                                  +1
                                                                                                                                                                  Для ключей массивов ни одна IDE не делает авкомплит. Отслеживать изменения в них гораздо сложнее (вручную). Нет проверки в рантайме со стороны языка (снова вручную и при вызове и в самой функции). и т.д.
                                                                                                                                                                    0
                                                                                                                                                                    Для ключей массивов ни одна IDE не делает авкомплит.

                                                                                                                                                                    +100! Иной раз только из-за этого меняешь mysql_fetch_assoc на \Doctrine\ORM\EntityManager::find
                                                                                                                                                          0
                                                                                                                                                          Ответил выше
                                                                                                                                                            +3
                                                                                                                                                            ну, как вариант:
                                                                                                                                                            use Vendor\Image\Convert as imgconv;
                                                                                                                                                            
                                                                                                                                                            imgconv\from("source.jpg")
                                                                                                                                                              ->crop([10, 10, 40, 40])
                                                                                                                                                              ->background(0xaabbcc)
                                                                                                                                                              ->quality(80)
                                                                                                                                                              ->regenerate(true)
                                                                                                                                                              ->to("thumb.jpg");
                                                                                                                                                            // vs
                                                                                                                                                            createThumbnail("source.jpg", "thumb.jpg", 10, 10, 40, 40, 0xaabbcc, 80, true);
                                                                                                                                                            
                                                                                                                                                              +2
                                                                                                                                                              Судя по комментам, написанным во время написания моего — такой вариант весьма мейнстримен
                                                                                                                                                                0
                                                                                                                                                                В случае с именованными параметрами это будет выглядеть также читабельно, при этом это уже будет частью языка(то есть не нужно реализовывать функции типа crop, quality).

                                                                                                                                                                createThumbnail(
                                                                                                                                                                  $from => "source.jpg",
                                                                                                                                                                  $crop => [10, 10, 40, 40],
                                                                                                                                                                  $background => 0xaabbcc,
                                                                                                                                                                  $quality => 80,
                                                                                                                                                                  $regenerate => true,
                                                                                                                                                                  $to => "thumb.jpg"
                                                                                                                                                                );
                                                                                                                                                                
                                                                                                                                                                0
                                                                                                                                                                Если с ООП, то можно наверное так:
                                                                                                                                                                class Crop
                                                                                                                                                                {
                                                                                                                                                                    public static $x1=0;
                                                                                                                                                                    public static $x2=0;
                                                                                                                                                                    public static $y1=0;
                                                                                                                                                                    public static $y2=0;
                                                                                                                                                                    
                                                                                                                                                                    public static function set($x1, $y1, $x2, $y2);
                                                                                                                                                                }
                                                                                                                                                                class ThumbPipe
                                                                                                                                                                {
                                                                                                                                                                   public static $source;
                                                                                                                                                                   public static $destination;
                                                                                                                                                                
                                                                                                                                                                   public static function set($source, $destination);
                                                                                                                                                                }
                                                                                                                                                                class ThumbProperty
                                                                                                                                                                {
                                                                                                                                                                   public static $backround;
                                                                                                                                                                   public static $quality;
                                                                                                                                                                   public static $forceRegenerate;
                                                                                                                                                                
                                                                                                                                                                   public static set($bg, $quality=80, $forceRegenerate=false);
                                                                                                                                                                
                                                                                                                                                                }
                                                                                                                                                                $crop = Crop::set(1, 10, 52, 30);
                                                                                                                                                                $thumb = ThumbPipe::set('/srv/ht...', '/srv..');
                                                                                                                                                                $params = ThubmParams::set('#FFEE33');
                                                                                                                                                                createThumbnail(ThumbPipe $thumb, Crop $crop, ThumbParams $params); 
                                                                                                                                                                
                                                                                                                                                                

                                                                                                                                                                Бр… как громоздко… первое что пришло в голову… ну или второе:
                                                                                                                                                                $crop = array(1, 50, 20, 30);
                                                                                                                                                                $params = array('#FFFAAA', 85, true);
                                                                                                                                                                createThumbnail($source, $destination, array $crop, array $params);
                                                                                                                                                                


                                                                                                                                                                Уж извините, спать хочется, возможно завтра будет стыдно за то что написал… В общем позвольте пог… кодить на ночь глядя :) Ну в общем функции с длинным списком параметров были есть и будут.
                                                                                                                                                                  0
                                                                                                                                                                  Так однозначно хуже читается. На мой вкус.
                                                                                                                                                                    0
                                                                                                                                                                    Да выше есть варианты и лучше. Но все равно в 100% не избавится от длинного списка параметров или длинной цепочки вызовов методов.
                                                                                                                                                                    0
                                                                                                                                                                    Ну в общем меня зациклило на «ну в общем», ну в общем вошел в рекурсию, ну в общем спать.
                                                                                                                                                                      0
                                                                                                                                                                      $crop = array(1, 50, 20, 30);
                                                                                                                                                                      $params = array('#FFFAAA', 85, true);
                                                                                                                                                                      createThumbnail($source, $destination, array $crop, array $params);
                                                                                                                                                                      

                                                                                                                                                                      Здесь абсолютно не решается проблема вызова функции с $source, $destination и $forceRegenerate, не вызывать же createThumbnail($source, $destination, array(), array(null, null, true);

                                                                                                                                                                      Класс же со статическими методами вообще не тру. Его ни расширить, ни замокать чтобы потестить, ни передать аргументом, ни завести два инстанса (следующий затирает предыдущий).
                                                                                                                                                                        0
                                                                                                                                                                        Я статические методы и переменные класса воспринимаю прежде всего как замаскированые глобальные…
                                                                                                                                                                    0
                                                                                                                                                                    Наконец-то они одумались! Нужна не строгая проверка на тип, а приведение.
                                                                                                                                                                    У меня несколько иное мнение на этот счет. Можете почитать эту ветку комментов, например. А если коротко — то в современных фреймворках объект, инкапсулирующий запрос, имеет методы для получения ключей с приведеднием к заданному типу. Поэтому строгая типизация, без приведения, лучше, чем приведение «без потерь», так как разработчик всегда знает, какой тип нужно ожидать в том или ином ключе, а строгая типизация делает валидацию неизбежной.