Введение в PHP 7: Что добавлено, что убрано

https://www.toptal.com/php/php-7-performance-features
  • Перевод
Одним из самых значительных событий, произошедших в мире PHP в 2015 году, стал выпуск PHP 7. Целых 10 лет отделяют его от выпуска первого релиза PHP с номером 5. С увеличением первой цифры в номере версии, в PHP 7 появилась масса новшеств, увеличилась и скорость работы.
Однако в седьмой версии была убрана устаревшая функциональность, что привело к некоторым проблемам с обратной совместимостью, затруднив перевод старых приложений на новую версию. Эта статья может послужить вам кратким руководством, если вы планируете написание новых или перевод своих существующих приложений на PHP 7.

Постойте, а где же PHP 6?


Если вы какое-то время не работали с PHP, вы можете удивиться, куда же пропал PHP 6, почему мы перепрыгнули с PHP 5 сразу на PHP 7? Что ж, я буду краток, выпуск PHP шестой версии не состоялся. Главной особенностью версии 6 была поддержка символов Unicode, поскольку в основном PHP используется в веб-разработке, вебу же нужна поддержка Unicode, поэтому её реализация имела смысл.

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

PHP6 был амбициозным, но отстойным. Посему мы занялись PHP7, в процессе пропустив шестую версию.

К сожалению, этот амбициозный план имел куда больше проблем, чем ожидалось. Большая часть кодовой базы должна была быть портирована для поддержки Unicode, как в случае ядра, так и в случае важных расширений, что оказалось утомительным и непростым делом. Это замедлило процесс разработки других возможностей языка, что расстроило многих PHP-разработчиков. Появились и другие барьеры, что привело к падению интереса к разработке встроенной поддержки Unicode, а со временем проект и вовсе оказался заброшенным.

А поскольку масса ресурсов, таких как книги и статьи, были написаны с использованием названия PHP 6 и поддержки Unicode, новой версии было решено присвоить имя PHP 7 — просто для того, чтобы избежать недопонимания.

Как бы там ни было, хватит копаться в мрачном прошлом. Давайте взглянем на то, что нового у нас появилось в PHP 7.

Войны за производительность, PHP 7 vs. PHP 5


Практически все обновления привносили небольшие улучшения производительности. Однако на этот раз производительность PHP, по сравнению с более ранними версиями, выросла куда более существенно, став одной из наиболее привлекательных особенностей PHP 7. Это было частью проекта “PHPNG” (“php new generation” или “php нового покления”, — прим. переводчика), затронувшего собственно сам Zend Engine.

Рефакторинг внутренних структур данных и добавление дополнительного этапа перед компиляцией кода в виде абстрактного синтаксического дерева — Abstract Syntax Tree (AST), привели к превосходной производительности и более эффективному распределению памяти. Цифры сами по себе выглядят многообещающе — тесты, выполненные на реальных приложениях показывают, что PHP 7 в среднем вдвое быстрее PHP 5.6, а также использует на 50% меньше памяти вовремя обработки запросов, что делает PHP 7 сильным соперником для компилятора HHVM JIT от Facebook. Взгляните на эту инфографику от Zend, которая отображает производительность для некоторых общеизвестных CMS и фреймворков.

PHP 7 выглядит знакомо, но он “заточен” под производительность. Усовершенствованный Zend Engine и итоговый прирост производительности привели к огромной разнице между ним и предыдущей версией.

Уменьшение потребления памяти позволяет более слабым компьютерам лучше обрабатывать запросы, предоставляя возможность выстраивания микросервисов вокруг PHP. Внутренние изменения, в частности реализация AST, также открывает возможности для будущих оптимизаций, которые могут ещё больше увеличить производительность. Новая собственная реализация JIT-компилятора разработана с намерением развития в будущих версиях.

Синтаксический сахар в PHP 7


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

Группировка объявлений импорта


Теперь мы можем группировать объявления импорта классов, находящихся в одном пространстве имён, в одной строке. Это поможет нам выровнять декларации неким, наделенным смыслом, образом или же просто сэкономит пару байт вашего кода.
use Framework\Module\Foo;
use Framework\Module\Bar;
use Framework\Module\Baz;


В PHP 7 можно написать:
use Framework\Module\{Foo, Bar, Baz};


Или же, если вы предпочитаете многострочный стиль:
use Framework\Module{
    Foo,
    Bar,
    Baz
};


Null-коалесцентный оператор


Решает распространенную проблему в PHP. Она возникает в случае, если мы хотим присвоить значение переменной, которое присвоено другой переменной, но если последней переменной значение не было присвоено, то присвоить некое явное значение. Часто проявляется при работе с пользовательским вводом.

До PHP 7:
if (isset($foo)) {
    $bar = $foo;
} else {
    $bar = 'default'; // присваиваем $bar значение 'default' если $foo равен NULL
}


В PHP 7:
$bar = $foo ?? 'default';


Можно использовать с цепочкой переменных:
$bar = $foo ?? $baz ?? 'default';


Оператор “космический корабль”


Оператор “космический корабль” <=> позволяет проводить трехуровневое сравнение двух значений, позволяя понимать не только их равенство или неравенство, но и то, которое из них больше при неравенстве, возвращая 1,0 или -1.

В этом случае мы можем предпринимать различные действия в зависимости от того, как различаются значения:
switch ($bar <=> $foo) {
    case 0:
        echo '$bar и $foo равны';
    case -1:
        echo '$foo больше';
    case 1:
        echo '$bar больше';
}


Сравниваемые значения могут иметь тип integer, float, string и даже быть массивами. Как разные значения сравниваются друг с другом? Смотрите в документации.

Новое в PHP 7


Конечно, в PHP 7 появилась новая, впечатляющая функциональность.

Типы скалярных параметров и подсказки (hints) по возвращаемым типам


В PHP 7 расширили ранее существовавшее объявление параметров в методах (классах, интерфейсах и массивах) путем добавления четырех скалярных типов — целого (int), с плавающей запятой (float), логического (bool) и строкового (string) в качестве возможного типа параметра.

Кроме того, опционально мы можем указать тип результата, возвращаемого функцией или методом. Поддерживаются типы bool, int, float, string, array, callable, имя класса или интерфейса и parent (для методов класса).
class Calculator
{
// объявляем, что параметры имеют целый тип integer
    public function addTwoInts(int $x, int $y): int { 
// явно объявляем, что метод возвращает целое
        return $x + $y;
    }
}

Объявление типов позволит строить прозрачные приложения, избегая передачи и возврата неверных значений при работе с функциями. Другие плюсы — появление анализаторов статического кода и IDE, предлагающих более ясное отображение кода при отсутствии документирующих примечаний DocBlocks.

Поскольку PHP слабо типизированный язык, некоторые значения параметров и возвращаемых типов будут приводиться исходя из контекста. Если мы передаем значение “3” в функцию, имеющую объявленный параметр типа int, интерпретатор будет рассматривать его как целое и не сгенерирует ошибку. Если вас не устраивает такое поведение, вы можете работать в строгом режиме — strict mode — путем добавки соответствующей директивы.
declare(strict_types=1);

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

Исключения движка


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

Ошибки, такие как вызов несуществующего метода, теперь не остановят скрипт, вместо этого будет сгенерировано исключение, которое можно обработать в блоке try catch, что явно улучшает обработку ошибок в вашем приложении. Это важно для некоторых типов приложений, серверов и демонов, поскольку фатальные ошибки, в противном случае, вполне могли привести к необходимости их рестарта. Тесты в PHPUnit также должны стать более удобными в использовании, поскольку фатальные ошибки могли уронить весь тестировочный проект. Исключения, в отличие от ошибок, могут быть обработаны для каждого теста отдельно.

PHP 7 выглядит и ощущается знакомым инструментом, но он нацелен на высокую производительность. Переработанный Zend Engine и прирост скорости работы приводят к большим отличиям от предыдущей версии.

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

До PHP 7 такой код привел бы к фатальной ошибке исполнения скрипта:
try {
    thisFunctionDoesNotEvenExist(); //ЭтаФункцияДажеНеСуществует()
} catch (\EngineException $e) {
    // Подчищаем за собой и записываем информацию об ошибке в лог
    echo $e->getMessage();
}


Анонимные классы


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

До PHP 7:
class MyLogger {
  public function log($msg) {
    print_r($msg . "\n");
  }
}

$pusher->setLogger( new MyLogger() );


Использование анонимного класса:
$pusher->setLogger(new class {
  public function log($msg) {
    print_r($msg . "\n");
  }
});


Анонимные классы полезны при тестировании юнитами, в частности при мокинге (имитации поведения реального объекта — прим. переводчика) при тестировании объектов и сервисов. Их наличие позволит нам избежать использования больших мокинг-библиотек и фреймворков путем создания простого объекта, поддерживающего интерфейс, который мы можем использовать для мокинга.

Функции CSPRNG


Две новых функции для генерации крипографически безопасной строки и целых. Первая возвращает случайную строку длиной $len:
random_bytes(int $len);


Вторая возвращает число в диапазоне $min… $max.
random_int(int $min, int $max);


Синтаксис Escape-кода для Unicode


В отличие от многих других языков, до PHP версии 7, в PHP не было способа указать в строке escape-последовательность для Unicode символа. Теперь с помощью escape-последовательности \u можно генерировать такие символы с помощью их кода из набора UTF-8. Это лучше, чем непосредственная вставка символов, лучше контролируются невидимые символы и символы, имеющие графическое отображение отличное от значения:
echo "\u{1F602}"; // выводит смайлик


Помните, что код, ранее работавший и использовавший пару символов \u, не будет корректно работать в версии 7 из-за изменившегося поведения.

Обновленные генераторы


Генераторы в PHP тоже получили несколько приятных новых возможностей. Теперь у них появился оператор return, который может быть использован для выдачи некоторого финального значения, актуального на момент завершения итерации. Его можно использовать для проверки корректности выполнения генератора. Например, узнать, выполнился ли он без ошибок, что позволит коду, вызвавшему генератор, корректно обработать любую возникшую ситуацию.

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

function genA() {
    yield 2;
    yield 3;
    yield 4;
}

function genB() {
    yield 1;
    yield from genA(); // 'genA' вызывается и отрабатывает в этом месте
    yield 5;
    return 'success'; // финальный результат, который мы позже можем проверить
}

foreach (genB() as $val) {
    echo "\n $val"; // выдаст значения от 1 до 5
}

$genB()->getReturn(); // вернет 'success' при отсутствии ошибок

Ожидания (expectations)


Ожидания (expectations) — улучшение функции assert() с сохранением обратной совместимости. Они позволяют использовать утверждения с нулевой стоимостью (zero-cost assertions) в рабочем коде и поддерживают возможность генерации пользовательского исключения при возникновении ошибки при отработке утверждения, что может быть полезно при разработке.

Функция assert() стала языковой конструкцией в PHP 7. Утверждения должны быть использованы только во время разработки и тестирования с целью отладки. Для настройки её поведения мы должны использовать две директивы.

  • zend.assertions
    1: генерируем и выполняем код (режим разработки) (значение по умолчанию)
    0: генерирует код, но обходит его во время выполнения
    -1: не генерирует код, делая его кодом с нулевой стоимостью (режим рабочего кода)
  • assert.exception
    1: генерируется при ошибке утверждения путем создания соответствующего объекта исключения или же путем генерации объекта AssertionError, если такой объект не был создан
    0: использует или генерирует Throwable так, как было описано выше, но генерируется только предупреждение (warning) на базе того объекта, а не генерация исключения с его помощью (поведение, совместимое с PHP 5)


Готовимся к переходу от PHP 5 к PHP 7


Появление версии PHP с номером 7 предоставило возможность изменения/обновления и даже удаления функциональности, которая считалась устаревшей или, некоторое время, уже ненужной. Такие изменения могут привести к проблемам с обратной совместимостью старых приложений.

Другая проблема, возникающая при появлении подобных версий, заключается в том, что библиотеки и фреймворки, которые для вас важны, могут не иметь обновлений, совместимых с новым релизом. Команда разработчиков PHP пыталась вносить изменения как можно в более высокой степени сохранив обратную совместимость для того, чтобы миграция на новую версию была как можно менее трудоёмкой. Относительно новые и вовремя обновляемые приложения, скорее всего, будет проще перевести на седьмую версию, тогда как для старых приложений необходимо взвешенное решение — стоят ли потраченные усилия полученных возможностей или же лучше и вовсе не обновляться.

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

Вас предупредили, так ведь?

Старые SAPI и расширения


Куда важнее тот факт, что были убраны старые и ненужные SAPI, такие как расширение mysql (но вы же его уже не используете, так?). Полный список расширений и возможностей, которые были удалены, вы можете посмотреть здесь и здесь.
Другие расширения и SAPI были портированы на PHP 7.

Очень много старых SAPI и расширений было убрано из PHP 7. Мы считаем, что за ними скучать не станут.

Однообразный синтаксис описания переменных


Это обновление привнесло некоторые изменения в части согласованности для конструкций переменная-переменная. Оно позволит использовать более прогрессивные выражения с переменными, что, в отдельных случаях, приведет к изменению поведения кода, как показано ниже:
                               // старый смысл           // новый смысл
$$foo['bar']['baz']     ${$foo['bar']['baz']}     ($$foo)['bar']['baz']
$foo->$bar['baz']       $foo->{$bar['baz']}       ($foo->$bar)['baz']
$foo->$bar['baz']()     $foo->{$bar['baz']}()     ($foo->$bar)['baz']()
Foo::$bar['baz']()      Foo::{$bar['baz']}()      (Foo::$bar)['baz']()


Это изменит поведение приложений, получающих доступ к переменным указанным способом. С другой стороны, вы сможете выделывать вот такие фокусы:
// вложенный ()
foo()(); // Calls the return of foo()
$foo->bar()();

//IIFE (Immediately-invoked function expression или немедленно вызываемое выражение функции) синтаксис как в JavaScript
(function() {
    // тело функции
})();

// Вложенный ::
$foo::$bar::$baz


Убраны тэги в старом стиле


Убраны или более некорректны открывающие/закрывающие тэги
<% ... %>, <%= ... %>, <script language="php"> ... </script>

Заменить их на корректные легко, но их использование в наше время выглядит несколько странно, не так ли?

Некорректные имена для классов, интерфейсов, трейтов


В результате добавлений, таких как типы возвращаемых значений и параметров, классы, интерфейсы и трейты больше не могут именоваться такими именами:

  • bool
  • int
  • float
  • string
  • null
  • true
  • false


Подобное именование может привести к некорректной работе существующих приложений и библиотек, но легко поддаётся исправлению. Следующие имена тоже нежелательно использовать в выше названном качестве, поскольку они зарезервированы на будущее:

  • resource
  • object
  • mixed
  • numeric


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

Полный список изменений, приводящий к несовместимости, можно посмотреть здесь.
Также вы можете использовать php7cc, этот инструмент проверит ваш код и отобразит потенциальные проблемы, которые могут возникнуть при переходе на PHP 7.

Но нет пути лучше, чем установить PHP 7 и увидеть всё воочию.

Потенциальные проблемы совместимости PHP 7



Совместимость инфраструктуры PHP 7


Многие сервисы хостинга добавили поддержку PHP 7. Это хорошая весть для провайдеров shared-хостинга, поскольку возросшая производительность позволит им увеличить число клиентских веб-сайтов без обновления железа, уменьшив текущие расходы и увеличив доходы. Что до клиентов, то они не должны ожидать резкого увеличения производительности в этих условиях, да и, говоря откровенно, shared-хостинг в любом случае не опция в случае приложения, ориентированного на производительность.

С другой стороны, сервисы, предлагающие частные виртуальные сервера или выделенные сервера, получат все прелести роста производительности. Некоторые PaaS-сервисы, такие как Heroku, давно поддерживают PHP 7, другие же, типа AWS Beanstalk и Oracle OpenShift, плетутся позади. Убедитесь на веб-сайте вашего PaaS-провайдера, есть ли у него поддержка PHP 7 или же она планируется в ближайшем будущем.

IaaS-провайдеры позволяют вам контролировать “железо” и устанавливать PHP 7 (или скомпилировать, если вам это больше нравится). Пакеты PHP 7 уже доступны для большинства IaaS-сред.

Совместимость программного обеспечения с PHP 7


В довесок к совместимости с инфраструктурой, вам также необходимо помнить о потенциальных проблемах совместимости с программным обеспечением. Известные CMS типа WordPress, Joomla и Drupal уже добавили поддержку PHP 7. Основные фреймворки, такие как Symfony и Laravel тоже сделали это.

Однако пришло время предостережений. Эта поддержка не распространяется на код третьих лиц в виде дополнений, плагинов, пакетов и т.п., к чему обращается ваш CMS или фреймворк. Проблемы могут быть, и ваша задача заключается в том, чтобы убедиться — всё готово для работы под PHP 7.

Для активных, поддерживающихся репозиториев, это не должно быть проблемой. Но заброшенные репозитории без поддержки PHP 7 могут сделать всё ваше приложение непригодным к использованию.

Будущее PHP


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

Библиотеки и фреймворки мигрируют на PHP 7, что приводит к появлению их новых версий. Я призываю вас попробовать семёрку и оценить полученные результаты. Может быть, ваше приложение уже совместимо с новой версией и готово работать на PHP 7, получая выгоды от его использования.
Поделиться публикацией
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
Комментарии 111
  • +2
    Спасибо!
    • –15
      Мне пришлось переписать большую часть приложения для использования PHP7. Плюс не думаю что CMS WordPress будет его поддерживать. Так как в wordpress один большой кастыль. Да и говорить что мы полностью поддерживаем PHP7 в тот момент когда его небыло, как то не вызывает доверия. К сожаления PHP7(точнее расширения к нему) падает с segfault на 2-х машинах и только на одном работает(на домашней машине).
      • +3
        Зачем писать комментарий, если вы не в теме?
        • +2
          Вроде как бы php7 производительность показывали на примере WP?
          Плюс все современные фреймворки уже поддерживают php7 (laravel, yii, zend, даже частично codeigniter)
          • +6
            Изначально тесты PHP7 проводили на Wordpress.
            Если же вам пришлось переписывать большую часть кода вашего приложения, то боюсь вы не знаете PHP. (сейчас перевел проект с 5.4 на php7, пришлось только несколько deprecated методов поменять)

            До выхода PHP7 Symfony говорили — что наша новая версия 3.0, полностью поддерживает PHP7.
            Но как? Ведь PHP7 еще не вышел? Просто постарайтесь ответить на этот вопрос и вы возможно все поймете.
            • –2
              Привидите документацию по этому поводу?
              • +2
                http://php.net/manual/ru/migration70.deprecated.php
                http://php.net/manual/ru/errorfunc.constants.php E_DEPRECATED
                Дасточно просто включить правильный уровен ошибок и все устаревающие методы вы уберёте задолго до выхода следущей стабильной версии. Ну а вещи вроде $$foo['bar']['baz'] — это гавнокод, которого не должно быть в нормальных проектах.
              • 0
                Очень просто: https://github.com/symfony/polyfill-php70 и фиксы касательно нового синтаксиса переменных и прочих мелочей. Остальное совместимо с PHP5
              • +1
                wordpress давно поддерживает php7
              • +6
                меня всегда удивляло почему возвращаемые типы сделаны в стиле Pascal(постфиксная форма), а тайп хинтинг параметров в стиле C(префиксная форма)
                • +1
                  Более того, если функция может вернуть null, помимо указываемого значения — ничего не выйдет.
                  Сейчас обсуждаются RFC по этому поводу, но почему этого не было сделано в релизе PHP7 — неизвестно.
                  • 0
                    В целом потому что тайп хинтинг уже был в PHP и реализован он был в стиле Си, потому пошли на такие вот вещи. А для возвращаемых типов — ну типа так читабельнее… функция foo которая возвращает строку. Ну и еще — так сделано в Hack.
                    Я вам больше скажу, в php 7.1 появится еще и тайп хинтинг для свойств объектов (возможно в 7.1) и там так же будет использоваться стиль Си что бы не вызывать затрудений при прочтении в случае использования выражений.
                  • –10
                    Шта? Только if else был до РНР7?
                    А такого не было?
                    $bar = isset($foo)? $foo: 'default';
                    Понимаю хочется прикукрасить, но чтоб настолько…
                    • +2
                      Сахар же. Уже был $bar ?: $foo, видимо ему в подмогу и добавили эту возможность. Удобно.
                      • 0
                        Если посмотреть на zend coding style, то там написано что не следует ипользовать, сокращённый синтаксис. И это не просто так, так как усложняет понимания кода, не всегда явно видно что вот такая строка есть где то в коде $bar = $foo ?? $green;. И потом не всегда понятно от куда $bar = 'red' когда ожидалось $bar = 'green'.
                        • 0
                          Я не очень понял почему не следует. Хотя сам стараюсь придерживаться наиболее читаемого и явного стиля кодирования, даже в ущерб производительности кода и первичного написания кода, но не вижу затруднений в восприятии $bar = $foo ?? $green. Оно и читается легко, и делает именно то, как воспринимается:
                          Как так нет $foo ?????? Ну ок, тогда бери $green.
                          • +1
                            Вы стараетесь я стараюсь, а начинающие программисты не утруждают себя ставить элементарные скобки, и любят сокращёный синтаксис. Не давно на стэковерфлоу
                               if(count=test)
                                    for(i=0;i<student.length;i++)
                                        if(student.check)  student.show() && student.showGorod() ;

                            лиш бы не ставить скобки )
                            • +3
                              Это ужасно. И проблема лежит не в плоскости программирования. Она сродни плохому почерку — проявление неуважения к тому, кто будет это читать.
                              • +1
                                Я вот переученный левша. У меня плохой почерк правой, а левой выходят нечитаемые каракули. Переучиваться на левую, родную для меня — уже поздно, стар я. Улучшать почерк, в 21-м веке для правой? Тоже не особо рационально.
                                Применение рукописных текстов в моей жизни такое, что если я буду писать левой, то мне хватит (если медленно писать, то даже читать можно).
                                Я вырос на бейсике и асм-z80. Поэтому иногда таки позволяю себе писать без скобок.
                                Не такой капец конечно, с вложенными циклами и т.п., максимум что я могу наговнокодить это
                                if($ok) $data = 'qwerty;
                                else $data = 'uiop';
                                Но бывает, грешен, каюсь.
                                Однако не считаю это проблемой — длину метода до 20 строк я соблюдаю более строго, тернарный оператор максимально избегаю (но буду использовать ?? когда перейду на 7, потому что ?? более очевиден).
                                • 0
                                  У меня тоже от рождения кривой почерк, поэтому я пишу полу-печатными буквами. Критерий один — читаемость. Говонкод тоже себе позволяю, но только если это одноразовый скрипт, который не предполагает перечитывания кем бы то ни было (мной тоже). Ах, да, в одном случае все-таки говнопочерк оправдан — когда стоит цель затруднить прочтение.
                                  • +1
                                    Вопрос цены.
                                    У Вас есть 40 часов рабочего времени. За это время нужно забутстрапить проект. Сделать Minimum Viable Product для заказчика, чтобы уже работали над функционалом и юзабилити, сделать общую структуру чтобы нужно было запускать мидлов, отдавать архитектуру на ревью, давать пилить ТЗ на подзадачи, строить работу и т.п.
                                    Вопрос:
                                    Код будут смотреть другие люди, код будете смотреть и Вы сами. Чем пожертвуете? Функционалом MVP? Временем на архитектуру? Лично я пожертвую проработкой кода отвечающего за детали. Потеряю пагинации там, граничные случаи и т.п., малозначимыми деталями стиля (например некоторые методы могут вырасти вплоть до 40 строк, периодически встречаться условные структуры как я написал выше и т.п. И да, некоторые такие вещи могут потом пережить даже релиз, если находятся глубоко, в незначительном месте, в принципе читабельны, и проходят тесты....
                                    • –1
                                      Если кратко, пожертвую чем угодно, но не читаемостью кода. Вероятно, я никогда не попадал в столь жесткие условия, когда мне пришлось бы 40 часов подряд говнокодить ради некого дедлайна. Но даже если предположить такую гипотетическую ситуацию, то, во-первых, 40 часов это обычно не 1.5 дня, а 7. Поэтому это не 40 часов и как минимум 80, и раз уж речь идёт о такой срочности, значит важность там тоже приличная, а значит можно поднапрячься. Во-вторых, я скорее пожертвую некоторыми моментами архитектуры и какими-то программирования хорошего кода (KISS, DRY и т.д.). Тем, что можно будет итеративно исправить. В-третьих, выбирая между качеством, сроками и стоимостью, почти во всех случаях я выбираю качество+сроки. В-четвертых, квалификация — это как раз тот момент, когда при одних и тех же исходных данных задачу можно решить либо быстрее, либо качественнее, либо дешевле. Чтобы расширить границы золотого треугольника, я работаю над квалификацией. Как будете поступать вы или он — это каждый себе сам решает исходя из уровня своего образования, жизненного опыта и конкретных условий и задач.
                                      • 0
                                        ради некого дедлайна

                                        У вас почасовая оплата, денег есть на 40 часов вашей работы (потому что это MVP, лишь потыкать идею воплати, что бы понять есть ли смысл вкладывать в нее деньги). Прототип.
                                        • 0
                                          У меня не почасовая оплата. И денег больше, чем на 40 часов моей работы. Зачем фантазировать о том, чего нет? Под любое высказывание можно подобрать такие условия, при которых оно будет верным.
                                          • 0
                                            У вас нет, у меня есть. Никто ничего не фантазирует, и у каждого разные задачи. И у вас они так же могут возникнуть, и в этом случае лучше подходить более прагматично. Ибо понятие "читабельности" кода — весьма субъективно. Для меня это возмоность по коду прочитать бизнес логику экперту в предметной области или просто другому человеку. А все остальное — эстетика, большая часть которой достигается за счет автоматизированных тулов, линтеров и т.д.
                                            • 0
                                              Совершенно с вами согласен относительно читабельности кода. Код понятен? Значит читабелен (для конкретного человека). И я уже упустил суть спора.
                                            • 0
                                              У вас нет почасовой оплаты? Печалька.
                                              Мы с братом в собственной фирме ведем почасовой учет собственного рабочего времени, причем с изменяющейся тарифной сеткой. Эту работу я делаю за 5 баксов, эту за 25, потому что это я мог бы кинуть верстальщику, а это за меня бы делал более дорогой человек, а тут работа стоит 5 баксов, но я считаю ее как за 25, потому что объективных причин не делегировать не было, и мне и так было что делать.
                                              Печалька когда люди не считают собственные ресурсы.
                                              Нет, бывает что задач хватает на 0,25 ставки, но берешь человека в штат потому что так дешевле, или стабильнее, или возможные авралы перекрывают и т.п., и тут можно и по целых 8 часов в день работать если работы на 2 часа. Но это хоть и не редкая ситуация, но частный случай. И если у вас именно так, то это у вас сайд-эффект а не у всех :)
                                              • 0
                                                Да, не почасовая. А за бизнес-результат. А время на размышления о проекте вы тоже учитываете?
                                                • 0
                                                  А размышление это не работа?)
                                                  Работа. Причем часто более дорогая чем работа по реализации.
                                                  • 0
                                                    Т.е. учитываете? Ну т.е. вот полчаса подумал о проекте, пока засыпал — утром проснулся и записал в тайм-трекер, как-то так?
                                                    • 0
                                                      За "полчаса перед сном" нужно штрафовать.
                                                      За "всю ночь снилась работа" нужно посылать к невропатологу.
                                                      Разовые сайдэффекты сна не вредящие здоровью попадают в статистическую погрешность. Наравне с "отвлекся во время поиска на гитхабе" и тп.
                                                      Если же это разумное осознанное и рациональное "думанье", например в очереди/пробке и тп, то почему бы его и не посчитать?
                                                      • +1
                                                        Черт) Два раза сегодня работа снилась. Хотя засыпал нормально… Это мне за выпендрежЪ)
                                                      • 0
                                                        А у вас часто возникают случаи когда вы засыпая думаете о работе? Это ваше личное время. Хотите — думайте, не хотите — не думайте. Вообще перед сном пол часика лучше вообще ниочем не думать, планомерно снижая температуру своего тела для более комфортного и продуктивного сна. А то что мозг задачи продолжает на подсознательном уровне решать — ну так это уже логать не обязательно.

                                                        У большинства порог "продуктивного" времени — 6 часов в день. Так что если вы не можете решить какую-то задачу за рабочее время — лучше отвлечься и спокойно поспать, дабы с утра свежим взглядом посмотреть на вещи. Как правило люди любят зацикливаться на определенных вариантах и упускают более удобные и правильные решения извиду.
                                          • +1
                                            В общем то всё от программиста зависит, изобретает он велосипед от незнания frameworks и элементарного composer или же активно пользуеться уже готовыми и от тестироваными решениями. В полне нормальный проэкт и по коду и по качеству с помощью фреймворка и композера, некоторые проэкты ставяться на "адекватные" cms. Как бы всё давно написанно, и авторизация, и регистрация, и новости не новости, блоги не блоги и т.д. Да и предвкушая вваш ответ, на более менее серьёзные проэкты, выделяеться адекватное время на проэктирование, разработку макета, разработка фронтенд и бэкэнд части, и наращивания функционала.
                                            п.с. Строители перед постройкой дома, разрабатывают чертежи, проэктируют комуникацию, и потом только строят начиная с фундамента. А не наоборот.
                                            • 0
                                              Ну вы либо пишете грамотную урезанную бету (архитектурно, компонентно и с читаемым кодом), либо одноразовый прототип который нужно выкинуть сразу.
                                              Но не запускать мидлов и отправлять на ревью архитектуры на базе сляпанного на коленке прототипа. Ей богу, это же ад для команды.
                                              • 0
                                                пф…
                                                простите господа, всё время забываю как работает человеческий мозг)
                                                Повторюсь:
                                                Я не говорил о том чтобы написать ОпенКарт (как пример говнокода) или Вордпресс с мыслью мол потом доделаем.
                                                Я говорил лишь о том, чтобы позволить себе мелкие шалости вроде написания методов по 30 строк или конструкций вида
                                                if($ok) $data = 'qwerty;
                                                else $data = 'uiop';
                                                (и именно таких, без дальнейших циклов и ветвлений в условиях)
                                                В ответ мне предлагают работать по 16 часов в день и забить на DRY и KISS (может еще и на SOLID забить?) лишь бы не говнокодить.
                                                По дедлайну. 40 часов или 4 часа это без разницы.
                                                • 0
                                                  Да, методы по 30 строк и прочие мелкие шалости, конечно же, дают огромное преимущество во времени. А что вы хотели услышать? Да, ок, можно сделать KISSSOLIDDRYархитектурузабиваянанекоторыемелочитипапростейшейразметкикоданормальныхименпеременныхипрочейлабудывоимячитаемостиачо.
                                                  • 0
                                                    Аргумент.
                                                    Только вот с именами переменных я таки мучаюсь если они живут больше 5 строк.
                                                    В меня палкой вбивали что если в коде комментариев меньше чем кода, то лучше бы ты его не писал, а потом когда поменялась идеология, то уже сам осознал, ценой мегабайтов кода в помойку, что сейчас комментарии заменяет простая структура и читабельное именование.
                                                    Так что да, могу сделать неформатированный условный блок, но отделю его пустыми строками и обязательно перед коммитом выровняю отступы если вдруг где покосил. Да, $key=>$value в цикле это как за здрасьте, а то и $k=>$v, но только если в пределах экрана… Часто ловлю себя на мысли "скотина, ты 10 минут над именем переменной думаешь, пиши транслитом первое попавшееся и поехали дальше"…
                                                    И да, верно именнованный код, который хоть в половину SOLID нечитабельным быть не может.
                                                    Хотя знаете… У меня тут разумный вопрос возник. А что, if без скобок, если он однострочный, без приколов со следующим циклом и т.п., с банальным присвоением. Ну пусть даже с таким же else идущим за ним, который встречается в коротком логически понятном методе, это что может хоть немного вызвать неудобство с читабельностью? Я всегда считал, что обязательность скобок в стандарты добавили по той же причине что и запятая у последнего элемента массива — удобство возможных дальнейших правок. За читабельность вообще не задумывался. Не вижу почему конструкция из 5-7 строк будет читабельнее чем из двух… Я не прав? Скажите кому это реально мешает? Может и вправду я не прав и упорствую как упорствовал раньше со своими отступами в 2 пробела...
                                                    • 0
                                                      Кодинг стаил этот как устав придуманый жизнью пример из лекции по стилю кодирования в C партирую на PHP
                                                          if (expression == true) 
                                                              return 'good';
                                                          return 'do not good';

                                                      В принципе читабельно, а так
                                                               if (expression == true) 
                                                                //  return 'good';
                                                               return 'do not good';

                                                      сломали логику, и не заметили.
                                                      • 0
                                                        А что кто-то пишет сокращенный формат (без скобок) в две строки? Это нечитабельно и неприемлимо.
                                                        Если бы первый ретурн был бы на той же строке, то сломать было бы невозможно.
                                                        Ну и тут гремучая смесь нарушений. Два возврата подряд это ад. В сложных структурах, в одном методе несколько return еще можно простить (хотя опять таки какого черта структура сложная?), хотя он и попахивает скрытым goto, но еще можно, но вот так вот в наглую, это хамство.
                                                        Ну и если уж про стиль говорите, то константа на втором месте, да еще и == а не === это попахивает гораздо больше чем отсутствие скобок.
                                                        Хотя чего это я? В детстве обожал обратную польскую, но сейчас знаю, но никогда-никогда не пишу константу на первом месте. Лень раньше меня родилась)
                                                        • 0
                                                          ну expression подразумевалась не константа а какон либо условие… с одной строкой тоже можно накасячить
                                                              if(expression) return 'good';
                                                              return 'not good';

                                                          и коментируем
                                                           // if(expression) return 'good';
                                                           return 'not good';

                                                          снова ошибка если предполагалось вернуть пустую строку при expression == true как и в следуещем примере.
                                                           if(expression) // return 'good';
                                                           return 'not good';
                                                          • 0
                                                            Если вы закомментировали условие, то вы понимаете что вы делаете. Это ретурн можно было закомментировать не поняв (и потому его нельзя переносить, что непонятки больше).
                                                            А про сторону условия я имел ввиду то, что рекомендуется писать
                                                            if(true === goodWork($work)) {}
                                                            а не
                                                            if(goodWork($work) === true) {}
                                                          • 0
                                                            А что кто-то пишет сокращенный формат (без скобок) в две строки?

                                                            Еще как пишут, например, в yii 1.x оно везде так :)
                                                                public function getDriverName()
                                                                {
                                                                    if($this->_driverName!==null)
                                                                        return $this->_driverName;
                                                                    elseif(($pos=strpos($this->connectionString,':'))!==false)
                                                                        return $this->_driverName=strtolower(substr($this->connectionString,0,$pos));
                                                                    //return $this->getAttribute(PDO::ATTR_DRIVER_NAME);
                                                                }
                                                            • 0
                                                              Смотрим PSR-2 и радуемся. А на то как делают остальные плевать.
                                                              • 0
                                                                На вкус и цвет :) (меня там { и ) { на новых строках раздражают нереально).
                                                                • 0
                                                                  Я отношу форматирование кода к категории "плевать", ибо есть всякие phpcs-fixer и т.д. так что можно крутить и вертеть кодинг стайлами как угодно.
                                                              • 0
                                                                yii1 вышел 8 лет назад и кодстайл там не меняется принципиально (см. yii2, где все по psr)
                                                          • 0
                                                            Посмотрите на свой код, написанный год назад и все вопросы сразу отпадут. А ещё лучше 2-3 коллегам покажите и попросите их в общих чертах рассказать что делают вот эти две страницы кода. Если ответ будет получен быстро, внятно и без мата, значит всё ок. Писать код читабельным — это искусство, не требующее особых затрат времени, поэтому страшилки про MVP за 40 часов это вобще мимо. Читабельность === понятность. ОченьДлинныеИЯкобыПонятныеИменаПеременных — это не про читабельность, это про кодозадротство, другая крайняя степень написания нечитаемого кода.
                                                            Про комментарии я для себя выработал такую стратегию: вот есть кусок кода, который когда-то кем-то должен поддерживаться. Так вот, мысленно удаляем весь код и оставляем только комментарии. И даём коллеге эти оставшиеся комментарии. Сможет он по этим комментариям восстановить функциональность? Если да, то комментарии необходимые. Не заснёт ли он от скуки, читая килобайты комментариев? Если нет, то комментарии достаточные.
                                                            В общем говоря, если надо писать код для машины и только для машины, то какая разница как он будет написан. Если хоть кто-то ещё это будет читать, кроме интерпретатора-компилятора, то я для себя выбрал приоритет такой: сначала — людям, потом — компилятору. И класть я хотел на того, кто мне поставил эти ограничения в 40 часов, нам с ним не по пути.
                                                            И ещё момент. Когда я еду на машине, то даже в 4 утра в чистом поле включаю поворотник на развилке условно-дороги. Потому что привычка. И с читабельностью то же самое. Даже если никто не будет читать… привычка уважать.
                                                            • 0
                                                              Две страницы кода? Да хоть пять.
                                                              Только они не должны быть связаны между собой, тогда хоть 100.
                                                              От комментариев я отказался когда понял что такое ООП.
                                                              Я писал комментарии с детства. В 89-ом написал первую программу. Тогда мне было 9 лет. В 1991-ом выкинул первую программу на 10 страниц, и написал ее с нуля, потому что разбираться со своим же кодом без комментов было дольше. С тех пор начал писать комментарии.
                                                              Потом уже в начале нулевых на практике понял что ООП я понимал неправильно, и что каждый маленький кусочек кода должен быть в отдельном методе (или отдельном классе) не потому что так положено там или еще чего, а тупо потому что я так смогу его и только его переопределить в наследнике, сохранив весь остальной код. Так я познал дзен DRY.
                                                              Но поскольку каждый блок (цикл, ветвление, набор однотипных присвоений и т.п.) я и так выделял комментариями, а мельче комментариев было мало, то комментарии плавно переползли в правильные имена…
                                                              Комментарии (если это не комментарий перед методом или свойством, или перед классом) в моем понимании это признание в говнокоде. Если ты спешил, или ради оптимизации пошел на грязный хак или еще чего — напиши комментарий. Если же всё нормально написано, то что он здесь делает?
                                                              • 0
                                                                Комментарии комментариям рознь. Как я сказал чуть выше, я стараюсь комментировать суть происходящего, а не реализацию (ну и реализацию тоже, если задумка не очевидная)
                                                    • 0
                                                      Я могу даже тестами пожертвовать, если сочту проект тривиальным. Полностью поддерживаю. Хотя конечно есть еще куча хитростей как не потерять время разработки и при этом оставить код сносно изолированным от изменений. Для этого как бы не нужно часы тратить на рисование UML и т.д.
                                                      • +1
                                                        Какие тесты на MVP, о чем Вы? Только те которые необходимы для того чтобы писать. Мокаем то что нужно, но будет потом, тестируем куски чтобы быть уверенным что можно идти дальше, но оформлять полноценные тесты и т.п. это я даже не рассматриваю в такой задаче.
                                                        У меня подход к подобному коду примерно как к обычному коду в учебниках. Хороший чтобы понять идею, но упаси Боже тащить его на прод. Но писать так чтобы выбросить тоже дорого. Если есть приемлимый уровень инкапсуляции, именования и грамотная декомпозиция, то реализацию уже могут за тобой подобьют люди с ценой часа в 2-3 раза ниже. А если у тебя от кода останется только понимание "как нужно", то опять нужно будет скелет делать самому....
                                                        • 0
                                                          Полностью поддерживаю.
                                                          • 0
                                                            Если есть приемлимый уровень инкапсуляции, именования и грамотная декомпозиция, то реализацию уже могут за тобой подобьют люди с ценой часа в 2-3 раза ниже.

                                                            И такое видели, правда на выходе обычно получается обычный говкод, сквозь который просматривается некогда изящная идея — печальное зрелище...
                                                            • 0

                                                              А почему нельзя тащить, если сделан качественно?

                                                              • +1

                                                                Нет никаких проблем в "сделано качественно". Есть проблема того что:


                                                                • мало кто делает качественно на этом этапе
                                                                • делать качественно MVP может быть пустой тратой денег, так как нет гарантии что дальше MVP проект уйдет развиваться. Более того, "качество" влияет на сроки. А на этом этапе чем быстрее — тем лучше. Далее уже, когда мы этот MVP покажем таргет группе какой-нибудь, тогда уже можно принимать решения о том чтобы увеличивать качество.

                                                                Причем это абсолютно не значит что мы должны делать MVP на тяп ляп. Если у нас там есть какой-то алгоритм который составляет 90% ценности нашего проекта, на него имеет смысл потратить чуть-чуть больше времени чтобы потом было проще его переносить. А вот делать идеальный UX или сразу расчитывать на большие нагрузки к примеру смысла нет от слова совсем. Конечно бывают ситуации когда UX это и есть 90% ценности приложения, когда у нас есть например продукт-конкурент и мы хотим отжать аудиторию тупо за счет этого. На этом этапе тогда достаточно сделать качественные мокапы/прототипы без всего по сути чтобы уже начать получать фидбэк и конвертировать его в дела.


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

                                          • 0
                                            А по мне так очень удобно $bar = $foo ?? 'default'; не надо писать лишний раз переменную, краткость сестра таланта
                                            • +1
                                              Сделано специально для того чтобы не писать isset каждый раз, т.е. ваш пример превращается в $bar = $foo ?? 'default';
                                              У некоторых таких проверок бывает больше одной на строку или условие, так что новый оператор определенно повысит читаемость кода в таких случаях.
                                              • +1
                                                очень хочется еще вот такую штуку:
                                                $foo ??= 'default';
                                                вместо $foo = $foo ?? 'default';
                                                возможно, кстати, и примут (https://wiki.php.net/rfc/null_coalesce_equal_operator).
                                                • 0
                                                  +1, тоже хочу видеть подобный оператор, заметно бы избавило боли в 5-ой точке при работе с многомерными массивами больших уровней. в coffeescript он отлично сжился в php потенциала еще больше может быть
                                                  • 0
                                                    кстати только что увидел, голосования уже оказывается прошли и все 100% были "за". так что можно надеяться что в ближайших версиях уже появится этот чудо оператор
                                              • 0
                                                random_int(int $min, int $max);
                                                А чем она отличается от mt_rand(int $min, int $max)?
                                              • +1
                                                Отличная статья, но у меня вопрос, это все изменения php7?
                                              • +3
                                                Ну так в конечном счете поддержка utf8 была полностью реализованна в версии 7 или нет? Спасибо.
                                                • 0
                                                  нет, и, как я понимаю, уже не планируется.
                                                  • +2
                                                    Боятся проблем как с python3, когда 8 лет спустя перехода нет ибо переписывать тонны строк для работы со строками корректно (вместо хедера) всем влом. python2.7 включает как раз лучшее из python3 при этом сохраняя привычный синтаксис (когда utf8 всего лишь дополнительная надстройка, а строки могут быть как байтами так и строками).
                                                    Полный список разницы тут http://sebastianraschka.com/Articles/2014_python_2_3_key_diff.html
                                                    Собственно причина именно в utf8 и байтах и отсутствии implicit конвертации. Все-таки utf8 ввод и чтение это больше как определенный use case, а не парадигма. В 90% случаев мы используем ascii. Большинство протоколов работают только с ними (собственно почему был придуман punycode).
                                                    Хотя с программистской точки зрения это верно, с пользовательской точки зрения это лишний геморрой и в дополнение к другим изменениям — просто проблема, которой есть отличное решение — использовать 2.7.
                                                    Ждем Py4.
                                                    Поэтому PHP7 отличная итерация и слава богу они не пошли путем PHP6 ибо иногда то что с дев. точки зрения верно — с точки зрения пользователя языка неверно.
                                                    • 0
                                                      > python2.7 включает как раз лучшее из python3
                                                      там нету async await

                                                      > Ждем Py4.
                                                      но зачем? когда есть на замену достаточно зрелые Go или Kotlin уже сейчас
                                                      • 0
                                                        там нету async await

                                                        То что только это заставило всех двигаться на py3, как говорят англичане, "speaks volumes".
                                                        но зачем? когда есть на замену достаточно зрелые Go или Kotlin уже сейчас

                                                        У Go куча своих проблем, по-мимо кривого синтаксиса (уж лучше писать на cython тогда), Kotlin, как вижу, все тот же брекетный синтаксис.
                                                        Все что Питону не хватает на самом деле (и что задержало его захват мира) это GIL. Избавиться от него и Питон бы стал мега популярным (ибо использовать multiprocessing для полноценного тредирования это верх дебилизма).
                                                • –1
                                                  Что-то пых потихоньку превращается в jav'у с динамической типизацией. Не очень это хорошо, имхо.
                                                  • +5
                                                    А Java в пых. Где-то мы встретимся :))
                                                    • 0
                                                      Кому как. Мне нравится. Наверное, потому, что я всегда на PHP писал как на джаве с динамической типизацией :-) Мне только дженериков теперь не хватает.
                                                      • 0
                                                        Может, и до них дойдет: https://wiki.php.net/rfc/generics
                                                        • +1
                                                          Боюсь, с формулировкой «As I'm not a C-coder myself, I encourage others to write a patch» шансов мало.
                                                        • 0
                                                          А как же перегрузка методов? :)
                                                          • 0
                                                            В языке с динамической типизацией это только создаст проблемы — пойди пойми, что там вызовется. Это в Java с обязательным указанием типов более-менее очевидно, да и то не всегда.

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

                                                            Уж лучше методы добавить.
                                                            • –1
                                                              В языке с динамической типизацией это только создаст проблемы

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

                                                              Но это не проблема языка. Только что кстати топик был про создание дат и извращения с static function — вот там перегрузка конструктора была бы очень к месту.


                                                              А еще было бы здорово видеть перегрузку операторов, оно конечно довольно редко нужно, но тем не менее...
                                                              • 0
                                                                Я скорее имел ввиду проблемы с понятностью такого кода. Примерно те же проблемы, что джависты тут рядом обсуждают про var, только в php оно уже так везде. Тем более, что тут еще и в рантайме — получится как в груви, а там оно неочевидно от слова совсем.

                                                                Перегрузка операторов — такая штука… Ей злоупотребить не легко, а очень легко. Вспоминается единственный пример (кроме очевидных с какими-нибудь комплексными числами), где это уместно — SQLAlchemy, там красиво получилось.
                                                                • 0
                                                                  Перегрузки не хватало во времена пхп4. Примерно так же как всё время дергался от точки для конкатенации вместо привычного плюса. Но как понимал почему точка а не плюс, и привык, так же и привык к отсутствию перегрузки. Так что соглашусь, что ну ее нафиг, особенно в пхп, где у нас основная проблема являющаяся следствием основного достоинства — низкий порог входа, и куча низкоквалифицированных бойцов…
                                                                  Хотя я в свое время истерил по поводу возвращения goto. Но ничего не произошло. Кто говнокодил, говнокодит и дальше, кто писал нормально, пишет и дальше. И ни разу не встретил goto ни там ни там))
                                                                  • 0
                                                                    Забавные/нестандартные операторы в PHP обязаны свои появлением убогому парсеру… А на низкоквалифицированных бойцов точно не стоит равняться.
                                                                    • 0
                                                                      Ну не нужно всё на убогость списывать.
                                                                      Привычный плюс неприменим потому что нестрогая динамическая типизация. И дальше по цепочке.
                                                                      Уродство с функциями от быстрой разработки, чтобы всё и сразу заработало — тянули готовые библиотеки не сильно зоботясь о приведении к единому виду.
                                                                      Быстрый выход на широкий функционал и всяческие упрощения типа динамической типизации это основа популярности пыха. Не было бы этих проблем, не было бы языка. Так бы и остался нишевым шаблонизатором)
                                                                      • 0
                                                                        Привычный плюс неприменим потому что нестрогая динамическая типизация.

                                                                        Скажите это JavaScript-у :)
                                                                        Быстрый выход на широкий функционал

                                                                        Он просто занял свободную нишу — не было тогда ничего специально для веб-а.
                                                                        • 0
                                                                          ЖС это да, аргумент. На счет "слабого парсера" убедили.
                                                                          Впрочем в общем выводе ничего не меняется — проще парсер, быстрее в продакшн.
                                                                          А на счет "просто занял свободную нишу" та это можно сказать про 90% крупных компаний и брендов.
                                                                          Они "просто" заняли.
                                                                          Меж тем потрать они в пять раз больше времени и сил на более качественный продукт, и они бы "свободную нишу" не заняли бы. Потому что она была бы уже занята, и им пришлось бы конкурировать с тем кто был бы там уже....
                                                                          • 0
                                                                            Во времена PHP 4 ничего похожего не было (да и веб был совсем другим) — можно было компилировать и пускать cgi (на shared hosting… лол...) или perl — обе альтернативы так себе :) Поэтому к тому моменту когда python и ruby пошли покорять веб эта ниша уже была занята :) С хостингами для PHP кстати тогда тоже было сильно лучше чем для чего-то другого (shared-ы с apache + mod_php, а вся остальная экзотика сильно дороже была), что тоже сыграло свою роль.
                                                                            • 0
                                                                              шареды с пхп это было позже. Когда язык уже был.
                                                                              И уже занял нишу.
                                                                              Не занял бы — ее бы занял какой-то из бейсиков с виртмашиной и архитектурой по типу VBA. Или еще что-то.
                                                                          • 0
                                                                            Зато в PHP точка явно означает кастинг всего к строке, а в JS "+" зависит от контекста, который не всегда очевиден — для надежности приходится к строке явно приводить, или писать что-то вроде '' +…
                                                                    • 0
                                                                      Я скорее имел ввиду проблемы с понятностью такого кода.

                                                                      Обычно какой то определенный тип всё равно неявно подразумевается, а как он выглядит "123" или 123 дело десятое. Даже в чужом древнем говнокоде времен php 5.3 состоящем из "функций+псевдо ооп+зачатки ооп" я не вижу анархии типов. И в js её тоже нет. Поэтому думаю что когда везде будут использоваться типы то и проблем или не будет или их будет не так много как вам кажется :)
                                                                      Перегрузка операторов — такая штука…

                                                                      Смотрю на портянки вызовов bc* и плачу...
                                                                      • 0
                                                                        С понятностью перегрузки — как раз знакомый, которому волей случая довелось поддерживать проект на Груви, вот только недавно жаловался, что перегрузка в рантайме — ад полный, и баг вида «вот тут вызывается не тот перегруженный метод», попал аж на продакшен и привел в итоге к серьезным последствиям (тестами там покрыто более-менее, не обнаружилось).

                                                                        C bcmath/gmp — очевидно нужно, на уровне php extensions такую поддержку сделать бы неплохо. А в userland — ну не знаю, не знаю, в С++ этим очень часто злоупотребляют.
                                                                • 0
                                                                  Перегрузка методов нужна только в языках со статической типизацией. Для PHP нужны именованные аргументы как в python.
                                                                  • 0
                                                                    1. (только мое мнение) Named Parameters на функциях с маленьким числом параметров не нужно, функции с большим их количеством — говногод. А еще очень глупо привязываться в своем коде к внутренним названиям параметров — это целая кучка радости после того как автор библиотеки её немного отрефакторит :)
                                                                    2. Не только или по вашему вот это читабельнее чем несколько методов?

                                                                    public function addItems($items) {
                                                                        $result = false;
                                                                    
                                                                        if (is_string($items)) {
                                                                            list($itemId, $itemCount) = explode(':', (string) $items) + array(0, 1);
                                                                    
                                                                            $result = $this->addItem($itemId, $itemCount);
                                                                        } elseif (is_int($items)) {
                                                                            $result = $this->addItem($items);
                                                                        } elseif (is_array($items)) {
                                                                            if (isset($items['item_id'])) {
                                                                                $result = $this->addItem($items['item_id'], $items['item_count']);
                                                                            } else {
                                                                                foreach ($items as $item) {
                                                                                    if (!$this->addItems($item)) {
                                                                                        $result = false;
                                                                                        break;
                                                                                    }
                                                                                }
                                                                            }
                                                                        } elseif ($items instanceof Collection) {
                                                                            foreach ($items->getItems() as $item) {
                                                                                if (!$this->addItems($item)) {
                                                                                    $result = false;
                                                                                    break;
                                                                                }
                                                                            }
                                                                        } elseif ($items instanceof MemberItem) {
                                                                            $result = $this->addItems($items->item);
                                                                        } elseif ($items instanceof X) {
                                                                            // и тут еще кучка разных поддерживаемых классов
                                                                        } else {
                                                                            throw new Exception();
                                                                        }
                                                                    
                                                                        return $result;
                                                                    }
                                                                    • 0
                                                                      А много это сколько? 5-ок параметров — иногда именованные уже нужны. Вот вам пример с функцией из 4-х аргументов, которую вы возможно использовали:
                                                                      assertEqual($actual, $expected, delta => 0.0001);

                                                                      пока же приходится писать так:
                                                                      assertEqual($actual, $expected, '', 0.0001);

                                                                      Согласитень, первый вараинт намного проще "читать". А читабельность и выразительность кода намного важнее.
                                                                      По поводу Ad-hoc полиморфизма — он не нужен в виде перегрузки методов а больше для операторов. В вашем коде с добавлением возможности "перегружать" методы, мы по сути просто ифы вынесли в чуть другие конструкции языка. В итоге у нас появляются методы объекта, делающие одно и то же но с разными сигнатурами что сильно усложняет интерфейс, и раздувает код, который его использует.
                                                                      Вместо этого лучше воспользоваться параметрическим полиморфизмом, пример которого вы собственно и привели. А еще лучше — полиморфизм подтипов.
                                                                      • 0
                                                                        А читабельность и выразительность кода намного важнее

                                                                        Магические числа — зло :) А с какой нибудь говорящей константой/переменной/настройкой разница уже небольшая.
                                                                        В итоге у нас появляются методы объекта, делающие одно и то же но с разными сигнатурами что сильно усложняет интерфейс

                                                                        Кучка методов гораздо читабельнее чем аналогичная портянка if-ов + чаще они делают не одно и тоже, а просто выполняют конвертацию к типам которые нужны оригинальному методу.
                                                                        и раздувает код, который его использует.

                                                                        Не совсем понятно почему — в вызывающем коде у нас в любом случае есть единственный метод addItems.
                                                                        • 0
                                                                          Магические числа — зло :)

                                                                          Это не магическое число, и для каких-то тестов нужна дельта в 0.0001 а где-то 0.01. Делать на каждый случай константу — не очень разумно с точки зрения поддерживаемости. Ну и опять же — это больше как кастыль а не решение проблемы. С именованными параметрами — это без проблем решается.
                                                                          Кучка методов гораздо читабельнее чем аналогичная портянка if-ов

                                                                          Вот только ифы мы не видим, как пользователи этого кода. Мы видим только метод, который делает то, что нам нужно.
                                                                          в вызывающем коде у нас в любом случае есть единственный метод addItems.

                                                                          Раз уж у нас в этом методе появилась куча if-в, значит либо у нас нарушен принцип единой ответственности, либо мы не воспользовались полиморфизмом подтипов, либо просто мы не правильно написали код. Мне об этом говорят:
                                                                          куча else if-ов, отсутствие аргумента $itemCount у метода, проверки на instanceof.
                                                                          • 0
                                                                            Это не магическое число, и для каких-то тестов нужна дельта в 0.0001 а где-то 0.01

                                                                            Неразумно как раз таки разбросать эти числа по всем тестам и потом страдать вспоминая что это и почему оно здесь именно 0.01, а не 0.0001, а может вообще 0.1 надо? :) Если не нравятся константы/переменные/настройки — можно добавить какой нибудь assertEqualFloat().
                                                                            Вот только ифы мы не видим, как пользователи этого кода. Мы видим только метод, который делает то, что нам нужно.

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

                                                                            Ну… альтернатива тут добавить методы типа addItem(), addItemFromMemberItem() и т.д. и использовать их, вот только это как раз ведет к усложнению интерфейса и в сложных системах размазывает нашу изначальную простыню по всему проекту — это еще хуже.
                                                                            Мне об этом говорят:

                                                                            Просто код немного утрирован :) в реальности там не все так страшно.
                                                                            • 0
                                                                              Можно константу сделать для пустой строки, ну или для NULL если мы передаем его в отсутствующем параметре и т.п. Это будет более читабельно, хоть и костылем… Соглашусь, что уж очень часто именованные параметры эмулируют паредачей массива. Нативный был бы приятнее.
                                                                          • 0
                                                                            Ну и кстати по поводу разрастания количества методов: вот там портянка что выше, она еще простая, в реальности же каждый if запросто может потянуть на 2-3 десятка строк сложной логики, которую придется вынести в отдельные методы… и… на выходе получить тот же самый раздутый код, но только с одним дополнительным if-ом. А между тем работу этого блока спокойно мог бы выполнять интерпретатор...
                                                                            • 0
                                                                              В данном конкретном случае было бы неплохо в phpUnit добавить метод assertCloseTo(float $actual, float $expected, float $delta = EPSILON). :-)
                                                                    • 0
                                                                      Не очень это хорошо, имхо.

                                                                      Что же в этом плохого? Просто не надо как на Java многие писать и все будет хорошо (я про шутку с фабрикой проблем). Объектную модель PHP слизал с java еще лет 10 назад, так что уж теперь удивляться.
                                                                    • +1
                                                                      Дошел до «обновленных генераторов», начал искал в гугле дополнительную информацию, нашел что пересекается с «итератором». Понял что я остался в php 4. Хорошая статья!
                                                                      • 0
                                                                        Отличная статья, очень понятно и подробно. Даже не знал про такую возможность в обратке исключения. Очень этого иногда не хватало. И наконец-то типизация, я её хотел ещё с выхода 5-й версии, при использовании ООП без неё как-то не очень живется.
                                                                        • 0
                                                                          Хотел поставить на новые вебсервера PHP7 под redhat. Но не смог скомпилить, так как убрали из экстеншинов библиотеку sybase-ct (нужна для проектов).
                                                                          Использовать freetds и odbc в этом проекте на этих новых вэбах не могу…
                                                                          • 0
                                                                            php7.0-sybase - Sybase module for PHP это расширение?
                                                                            • 0
                                                                              вы наверное увидели это в пакетах Дебиана, там оно есть.
                                                                              Сейчас в исходниках исчезли пакеты для компиляции этого модуля. Раньше были здесь — /ext/sybase_ct
                                                                              Пробовал брать их от ветки 5.6 — непомогло, появляются ошибки
                                                                              • 0
                                                                                https://packages.debian.org/sid/php/php7.0-sybase тут есть пакет с исходняками.
                                                                                • 0
                                                                                  с дебианом не очень знаком, но при попытке скачать исходники, качаются пакеты .deb под определенную архитектуру. Все же думаю это не то что я ищю, так как там уже скомпиленая бибилиотека внутри .so
                                                                                  Мне же нужны исходники для компиляции самой PHP с поддержкой sybase-ct
                                                                                  • 0
                                                                                    Нет таких исходников, sybase-ct выкинули.

                                                                                    Разве что взять исходники из php5 и портировать под семерку самостоятельно.
                                                                          • 0
                                                                            Меж тем, use \Some\Name\Space* не работает ни под каким соусом, мать его за ногу…
                                                                            • 0
                                                                              Может быть вы в курсе, но можно писать так:
                                                                              use \Some\Name\Space;
                                                                              
                                                                              $obj = new Space\Classname;

                                                                              это и в пятой версии работает.

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