PHP слоник для привлечения внимания


Шутки про PHP — уже отдельный жанр в различных сообществах программистов. Некоторые не любят PHP, потому что {lang_name} намного лучше. А кого-то он вполне обоснованно расстраивает.


Я же PHP люблю. Не смотря на его косяки. Этот язык был создан для конкретной цели и решает он свою задачу хорошо. Схема "принял — обработал — отдал — умер" очень эффективна и решает проблему небольших утечек памяти.


В моей работе PHP используется постоянно. Так сказать, это основной backend язык, используемый в моих проектах. За время работы у меня появились некоторые пожелания и замечания. Решил поделиться с обществом. Кому интересно, добро пожаловать под кат.


Традиционный дисклеймер
Этот пост вряд ли изменит мир. Да и не об этом он. Пост, скорее, о наболевшем. Много субъективных моментов из разряда "я так считаю" или "я так хочу". Предупреждаю заранее, чтобы все были готовы.

1. Неявное временное преобразование примитива в объект


Проще объяснить на примере. В JavaScript мы можем обращаться к строке и массиву как к объекту.


let str = "1,2,3";

let arr = str.split(",");

arr = arr.map(_ => _ * 2);

console.log(arr); // [2, 4, 6]

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


В JavaScript, насколько мне это известно, массив уже является полноценным объектом, а строка хранится в виде примитива. И при необходимости, строка преобразуется в объект String, происходит вызов необходимого метода.


Почему бы в PHP не сделать что-то похожее?


$str = '1,2,3';

$arr = $str->explode(',');

$arr = $arr->map(function ($i) {
    return $i * 2;
});

var_dump($arr);

// Или даже так:

$str = '1,2,3';

$arr = $str
    ->explode(',')
    ->map(function ($i) {
        return $i * 2;
    });

var_dump($arr);

Десятки функций, связанных со строками и массивами можно было бы убрать в классы String и Array. Написание кода в функциональном стиле не был бы столь мучительным процессом.


$arr->keyExists(...);
$arr->map(...);
$arr->filter(...);
$arr->keys(...);
$arr->push(...);
$arr->pop(...);
$arr->exists(...); // in_array

$str->repeat(...);
$str->join(...);
$str->trim(...);
$str->replace(...);

Другая сторона этого вопроса: объектная реализация примитивов может имплементировать различные интерфейсы. Что нам это дает? Можно свободно избавляться от таких функций, как is_iterable, is_numeric, is_countable, и переходить на иcпользование instanceof \Countable, \Traversable и п.р. Ну разве не прекрасно?


2. Дженерики


Впервые с дженериками я познакомился, когда изучал Java. Мощь дженериков сложно переоценить. Они могут использоваться в DI контейнере, когда указываем тип объекта, который хотим получить:


$service = $container->get<SomeService>();

Они полезны при реализации различных коллекций, а также репозиториев (Yii2 Query или Doctrine).


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


public function getItems(): Array<Item>

public function setItems(Array<Item>): void

Выглядит уже инетересно, согласитесь? Теперь и мы уверены, что всегда получим массив объектов определенного класса, и IDE точно знает, что подсказывать без всяких PHPDoc блоков. Но мы ведь можем не только массивы передавать, но и свои коллекции:


public function getItems(): Collection<Item>

public function setItems(Collection<Item>): void

Хотя синтаксис массива объектов как PHPDoc мне нравится больше (SomeObject[]), этот вариант тоже хорош. В любом случае это лучше, чем то, что есть сейчас (либо array, либо ничего).


3. Аннотации или декораторы


В Java аннотации используются с версии 1.6 (придуманы они были еще раньше). Доступны они через рефлексию. (Java знаю плохо, поэтому исправьте, если где-то не прав)
В JavaScript существует похожий механизм — декораторы (не уверен, что они являются частью стандарта, но уже повсеместно используются благодаря Babel).
А что есть в PHP? В PHP есть PHPDoc блоки, которые созданы сугубо для документирования. И разработчики выжимают из этого все, что могут. Примерами служат такие замечательные библиотеки, как Doctrine и PHP-DI.


Я об аннотациях задумался, когда подключил компонент Symfony Event Dispatcher. Когда я создаю класс-подписчик, который реагирует на события в системе, я должен имплементировать метод getSubscribedEvents, который возвращает массив, где в качестве ключа — идентификатор события, а в качестве значения — имя метода, реагирующего на событие в этом классе. Это простой и эффективный способ решения проблемы. Эффективный, но не удобный. Почему? У меня идентификаторы событий хранятся в константах классов. Если я хочу найти подписчиков на какое-то событие, я произвожу поиск по коду, который использует константу-идентификатор, меня перекидывает в метод getSubscribedEvents, где я беру название метода(ов), и ищу этот метод(ы) в классе. Если мне нужно узнать, на какое событие реагирует какой-либо метод, то мне нужно проделать ровно то же самое, только в обратном порядке. Слишком много шагов для столь простого действия. Опять же, если я хочу переименовать метод-подписчик, я не могу просто взять и воспользоваться возможностями IDE (поиск по тексту — функция редактора, а не IDE). Это придется делать вручную.
Но как оно могло бы быть, если бы существовали аннотации:


@EventSubscriber(ItemEvents::CREATE)
public function itemCreated(ItemEvent $event)

Как по мне, это очень удобно. Производя поиск по константе, я сразу увижу, какой метод его использует. Без всяких дополнительных действий. И наоборот: мне не нужно куда-то еще лезть, чтобы увидеть, на какое событие среагирует этот метод.


Из плюсов сразу хочется отметить поддержку IDE, если это будет внедрено в язык. Аннотации можно импортировать также, как и обычные классы, что избавляет от необходимости писать namespace'ы.


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


4. Короткий синтаксис функций.


До знакомства с JavaScript при любых действиях с массивом (фильтрация, маппинг и п.р.) я использовал императивный подход:


$input = [...];
$output = [];

foreach ($input as $i => $item) {
    // logic
    $output[$i] = $item;  
}

После изучения ReactJS + Redux мне больше понравился функциональный подход к решению подобных задач:


let output = input.map(item => {
    // logic
    return item;
});

Но мне не нравится, как это выглядит в PHP:


$output = array_map(function($item) {
    // logic
    return $item;
}, $input);

А теперь давайте объединим первую идею с этой:


$output = $input->map(($item) => {
    // logic
    return $item;
});

Вот согласитесь, в PHP не хватает чего-то, что заменило бы function($item) {} на что-то более чистое и эллегантное. И совсем не обязательно, чтобы это что-то отличалось по функционалу от обычной записи (как это есть в JS). Главное, чтобы оно занимало меньше места и не создавало шум для глаз разработчика. Об этом уже говорилось ранее не мной. И даже есть такой RFC. Но это актуально, не так ли?


5. Асинхронность


Я не говорю про многопоточность. Вот в JavaScript есть Promise. Я запустил несколько задач асинхронно, дождался окончания их работы и пошел работать дальше.


В PHP может быть множество задач, которые хотелось бы сделать асинхронно, не дожидаясь окончания выполнения. На ум сразу же приходят работа с большими БД запросами и HTTP запросами. Чтобы составить большой отчет, приходится либо долго ждать, либо пользоваться сторонними решениями, типа очередей. В моем случае, в проекте в большом количестве используются Slack уведомления и Mailgun оповещения. За один клиентский запрос может быть отправлено около десятка HTTP запросов. Почему бы не запустить это все на фоне, а клиенту уже отдать страничку? Это возможно. Но простого решения из коробки нет.


Знаю про существование расширения PThreads, но насколько это просто решение из коробки? К тому же, это про настоящую многопоточность, которую нужно уметь готовить.


6. Использование выражений везде


Например в значениях параметров по умолчанию:


class Money {
    __constuct($currency = new Currency('RUB')) {...}
}

Или даже в свойствах класса:


class Money {
    private $currency = new Currency('RUB');

    public function setCurrency(Currency $currency) {...}
}

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


На самом деле, это всего лишь сахар, который чуть-чуть уменьшит объем кода в некоторых случаях, потому что можно сделать так:


class Money {
    private $currency;

    __constuct(Currency $currency = null) {
        $this->currency = $currency ?? new Currency('RUB');
    }
}

Использование выражений на создании объектов налету не заканчивается. Вместо этого можно было бы подставить любое выражение:


public function someMethod($value = $this->defaultValue): void

public $statuses = SomeClass::getStatuses();

Мне было бы очень удобно.


7. Указание типа переменным


Тут много написать не получится, так как (1) и так все понятно, (2) и так всем известно. Хочу сказать только то, что из PHP не обязательно делать язык со строгой типизацией. Достаточно только дать такую возможность. А дальше пусть каждый решает сам, как ему пользоваться этим. Но для тех, кто пришел с языков со строгой типизацией, PHP станет более привлекательным.


8. Убрать function


Не совсем понимаю необходимость ключевого слова function в указании методов класса.


public function someMethod()
// Или
public someMethod()

Это чисто субъективный момент. Но в тех языках, которые я знаю помимо PHP, а именно Java и JavaScript, я этого не наблюдаю. Действительно, а зачем? Семантически это слово никакой роли не играет. Я и без того пойму, где функция, а где свойство. Но кажется, что убрав лишние 9 символов, будет немного больше места для аргументов и меньше визуального шума. А это небольшой, но плюс.


9. Навести порядок


Беспорядок, пожалуй, самый весомый аргумент против языка. Сложно отрицать, что в PHP много странных непоследовательных решений, в отношении названия функций, порядка аргументов и п.р. Всё понимаю: обратная совместимость, "исторически сложилось", влияние других языков. Но нужно двигаться дальше!
Как вариант, можно большинство функций перенести внутрь объектов, как я описал в самом первом пункте, остальные реализовать в качестве статических методов этих классов (например Array::method()), а все остальное пометить как deprecated. А в следующей версии повыкидывать все!


Как по мне, PHP неплохо развивается как ОО язык, и большинство функций, констант и п.р. можно переместить в классы (json_encode -> Json::encode, cUrl).
Если бы кто-нибудь сделал расширение, которое решает эти проблемы, переносит все функции в статичные методы классов, написал полифил, если вдруг расширение не установлено, и для Codesniffer написал варнинги при использовании старых функций… Я бы уже сейчас стал использовать его. Мне кажется, что не только я. Вопрос только в том, что это должно быть именно расширение, которое максимально эффективно прокидывает аргументы из метода в нативную функцию.


Вместо заключения


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


Я прекрасно понимаю, что многое из того, что я описал, почти невозможно сделать без серьезных проблем с производительностью, либо корневых изменений в движке. Но кто мешает хотеть?) К тому же, многое из описанного, наверняка, хочу не только я. Поэтому, есть хороший шанс увидеть все это в будущем.


Еще что хочу сказать. Это все субъективно. Это то, что хочу конкретно я. К тому же, на мое мнение повлияло изучение Java. И мне понравились некоторые возможности этого языка. Но это вовсе не говорит о том, что так надо или что это единственно верное решение.


А что Вы хотели бы увидеть или изменить в PHP?

Комментарии (188)


  1. m03r
    02.05.2018 13:47
    +2

    1. vtvz_ru Автор
      02.05.2018 14:47
      +5

      Было бы все просто, если было бы все просто. RFC писать без предварительной реализации и без тестов не имеет особого смысла (там так и сказано). Я бы с удовольствием поддержал проект кодом. Но сколько времени займет изучение языка C и исследование внутренностей проекта, прежде чем я смогу написать что-то толковое? С учетом полной рабочей занятости, на это могут уйти годы...


      1. Fesor
        03.05.2018 00:55

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


        Но давайте вспомним почему в php нет вещей в статье:


        1. синтаксис с "точкой" (точнее с -> для операций над скалярами) — нет и не будет потому что заведомо проигрышная штука. Она в разы проигрывает тому же pipe оператору в плане гибкости и сложности реализации. А то что люди "привыкли" — это вопрос к тому что нужно правильно людям подать идею что бы они забросили мертвые концепты. PHP на js, там нет прототипного наследования, манкипатчинг в php никто не хочет (и правильно делает), так что нечего.

        вот pipe оператор дело другое:


        $result = [1, 2, 3, 4]
           |> usort(($a, $b) => $a->foo <=> $b->foo)

        1. дженерики: сложна, существует RFC и даже существуют люди которые чето пилят и обещают нам дженерики в 8-ой версии. Но есть нюансы с описанием поведения дженериков (RFC не доконца проработана и уже слишком большая) + есть целая гильдия противников подобных вещей в php. Ну и главная проблема — то что php единственный язык из тех что я знаю который делает подобные проверки в рантайме. Это глупо и в целом только по этой причине реализация тех же дженериков усложняется на порядки (потому например мы не имеем тайпхинтинга для пропертей — была реализация но сделать без сущенственного оверхэда на рантайм не вышло).


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


        3. короткие функции напоролись на ограничения парсера. Символ => уже занят в выражениях, как и ->, варианты из Hack (==>) никому не понравились, варианты fn($x) => $x **2 не нравятся потому что новый кейворд + нарушение обратной совместимости (кто-то уже может юзать функцию fn). Ну и последние варианты опять же уперлись во вкусовщину.


        4. Асинхронность. Вот тут в статье написан полный бред и чушь. Начиная с того что pthread тут не причем, и заканчивая тем что async/await и event loop на уровне ядра было бы круто, но не обязательно.

        Было обсуждение ввести в php stackless корутины но вы можете юзать их и так через экстеншен. Да и решений для асинхронности полно.


        С другой стороны среднестатистический php разработчик понятия не имеет как работает сборщик мусора и в целом весьма сильно полагается на модель "а оно потом умрет и все будет ок" что плохо совместимо со всей этой культурой. Все это делает фичи в духе асинхронности мало востребованными, ибо те кто хотят и так могут. Просто не так красиво и удобно.


        1. Невозможно. Просто в силу того как реализован php. Ну то есть не то что бы невозможно, но сложно. Да и не очень то и нужно.


        2. Тайпинг для переменных и пропертей — была даже реализация но как я писал выше — из-за любви к проверке типов в рантайме никто ради этой фичи не стал жертвовать 30% оверхэдом по рантайму.


        3. наследие лет и ограничения лексера/парсера языка. Вроде как сейчас я не вижу особо проблем с тем что бы делать этот кейворд обязательным.


        4. Меня всегда бесило это нытье. Никто и никогда не мешал никому сделать пакет на packagist с элиасами для функций раскиданными по нэймеспейсам. И вместо того что бы решить проблему люди просто продолжают ныть.

        p.s. я не то что бы говорю что php обречен, а скорее предлагаю перестать ныть и надеяться на то что php станет тем языком который нам хочется видеть.


        Есть проекты вроде preprocess.io которые решают все озвученные проблемы (либо минимизируют эффект), есть анализаторы вроде psalm, есть куча крутых решений проблем, есть language server в конце концов и возможность писать свои DSL и синтаксисы с транспайлом в php и совместимостью. Но нет, всем надо просто и из коробки.


  1. nosennij
    02.05.2018 14:18
    +1

    explode, нет?


    1. vtvz_ru Автор
      02.05.2018 14:18

      Спасибо, исправил


  1. Gemorroj
    02.05.2018 14:45
    +4

    По поводу асинхронности — давно делают файберы, но пока в ядро протащить не получается (https://wiki.php.net/rfc/fiber, https://externals.io/message/101808).
    А сторонних реализаций eventloop хватает.
    Да и вообще, почти по всем пунктам, уже были или попытки что-то сделать по указанным направлениям, но протащить дальше rfc не удавалось.


  1. Alukardd
    02.05.2018 15:22
    -2

    1. m0rtis
      02.05.2018 17:12
      +2

      There are currently no reports of these vulnerabilities being exploited in the wild.

      Ну и вообще говоря прикольно видеть ченджлог в качестве отчета об уязвимости:))


  1. Suvitruf
    02.05.2018 15:50
    -9

    PHP может стать еще лучше
    А может не стать.


  1. justmara
    02.05.2018 16:07
    +2

    Указание типа переменным
    … не обязательно делать язык со строгой типизацией

    снова кто-то путает строгую (сильную) и статическую типизацию


  1. vlreshet
    02.05.2018 16:16

    Пункт номер 1 — это было бы прекрасно. После JS очень коробит делать что-то вроде

    $something = explode($list, ",");
    
    $result = [];
    foreach($something as $item){
         $result[] = doAction($item);
    }
    
    Вместо
    $something = $list->explode(",")
                      ->map($item => doAction($item));


    1. oxidmod
      02.05.2018 16:28
      +1

      Гляньте на эти коллекции
      Для большинства случаев они очень неплохи.


      1. SerafimArts
        02.05.2018 19:18
        +1

        Лучше ларовские: laravel.com/docs/5.6/collections У них плюшек на несколько порядок больше, включая High Order Messaging и прочую дичь)


        1. symbix
          02.05.2018 23:26

          Если уже используется laravel или lumen, то ага. А так целый illuminate/support тащить, да еще с этими фасадами — ну как то не знаю.


          1. Samouvazhektra
            02.05.2018 23:36
            +1

            1. Snart
              03.05.2018 14:36

              nayjest/collection
              composer require nayjest/collection


              1. SerafimArts
                03.05.2018 15:06

                И всё же оригинал лучше, имхо. Это раньше он половину ядря тянул за собой, сейчас же только контракты (набор из дестяка интерфейсов), что не является фатальным.

                Зато получаем поддержку километрового сообщества, актуальность и набор хелперов, которые будут использоваться 146% если знать об их существовании (например, array_first/last или class_basename).

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


                1. VolCh
                  03.05.2018 15:56
                  +2

                  > которые будут использоваться 146% если знать об их существовании

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


    1. Bal
      02.05.2018 20:08
      +1

      Что-то типа такого?


      $result = array_map(function($x) { return $x*$x;}, explode(',', '1,2,3'));

      Array
      (
          [0] => 1
          [1] => 4
          [2] => 9
      )


  1. springimport
    02.05.2018 16:54

    Раз такое обсуждение пошло, то внесу и я свои пожелания.

    Конструкторы и di
    После работы с magento 2 стало очевидно что нужно что-то делать с конструкторами когда внедряется di. Пример класса. Возможно, использование выражений на месте, как сказано в статье, спасет ситуацию.

    Наследование классов
    Знаю что проблема не php, а многих языков. Так и не пришел к хорошему решению проблемы с наследниками.
    1 случай: имеется класс для выборки данных который нужно закэшировать. Можно сделать наследование и заменить все методы на кэширующие. Если класс под интерфейсом, то реализацию интерфейса. В обоих случаях придется дублировать все методы. Как это решить — не понятно.
    2 случай: в magento 2 есть возможность переопределять классы (preference), но переопределить класс от которого кто-то наследуются напрямую (extends /Class) — нельзя. А класс еще может быть абстрактным. В итоге получаем кучу наследников которые нужно переопределять чтобы добавить общий метод. И простого решения нет. Трейт лишь облегчит ситуацию.


    1. m0rtis
      02.05.2018 17:48
      +1

      Пример класса. Возможно, использование выражений на месте, как сказано в статье, спасет ситуацию.

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


      1. oxidmod
        02.05.2018 18:05

        Magento — суровый enterprise, еще и щедро приправленный legacy


      1. OnYourLips
        03.05.2018 07:15
        +1

        После работы с magento 2 стало очевидно что нужно что-то делать с конструкторами когда внедряется di. Пример класса.

        С этой проблемой прекрасно справляются код-ревью и найм более квалифицированных специалистов.


    1. VolCh
      02.05.2018 20:04

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


    1. KAndy
      03.05.2018 00:00

      Слегка не по теме, но на 2 случай в мадженте есть плагины


      1. springimport
        03.05.2018 15:47

        Как и все в мадженте, они как бы есть, но использовать можно только где-то в 20% случаях.
        Добавить метод через плагин? Нельзя.
        Сделать замену метода где используются приватные методы? Можно, но бессмысленно (нельзя).

        Плагины не отменяют проблему с наследниками. Точно так же нужно работать с каждым по-отдельности.


    1. symbix
      03.05.2018 00:19

      Мне вот недавно пришлось с головой окунуться в старый индокод, с десятками global в начале функций. В этом вашем примере класса из Magento вижу по сути то же самое, только приправленное ООП.


      Не-не, как раз хорошо, что инъекции через конструктор. Были бы property injections по типу @Autowired — было бы не так заметно, какой там ад.


      1. KAndy
        03.05.2018 00:32

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

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


        1. symbix
          03.05.2018 02:58

          Вы так уверены, что можете поменять вот такую зависимость? :-)


          Не, SOLID работает, только когда все буковки сразу.


          1. springimport
            03.05.2018 15:54

            Я думаю что да. Просто это может потребовать кучи времени.


            1. symbix
              03.05.2018 16:21

              За кучу времени я и global-ы индусские переписать могу, вообще с нуля :-)


              1. springimport
                03.05.2018 16:56

                Мне кажется что если бы разработчики применили полноценное ddd то m2 если бы и вышла, то к концу десятилетия. Это если не смотреть сколько лет ушло на фиксы багов с 2.0…

                А еще при работе с системой проходят проверку на прочность все компоненты: php, mysql, phpstorm, composer. Я вот не уверен что разработчики composer планировали что обычный проект будет грузить сотни мегабайт кода. Или в jetbrains разрабатывали phpstorm только для тех у кого ssd… Куда еще увеличивать кодовую базу.


                1. symbix
                  03.05.2018 17:52

                  Да я это все прекрасно понимаю, у самого тонна криво спроектированного легаси, с которым приходится жить. Я это все к изначальному тезису про "надо что-то делать с конструкторами". Не надо. :-)


                  1. springimport
                    03.05.2018 18:10

                    На надо во времена 5.6-7.0, уверен что на 7.5 вообще все перейдут на di и в каждом проекте будет вот это вот объявление параметра, занесение в конструктор, назначение в конструкторе, генерация docblock. В наследнике хочешь написать что-то в construct? Будь добр, тащи все зависимости в предок.

                    Запрещать подход я не предлагаю. Я за расширение: в простых случаях по-старинке, а с десятком зависимостей по-другому.


                    1. symbix
                      03.05.2018 19:59

                      А, в этом смысле. Тут можно позаимствовать сахарок из того же Typescript:


                      constructor(private foo: FooInterface, private bar: BarInterface) {}

                      Хотя в нормальной IDE с генерацией приватных свойств и присваиванием в конструкторе проблем нет, все делается автоматически.


                      Docblock, который не добавляет никакой информации, а просто дублирует сигнатуру — нафиг не нужен. Если требуется правилами оформления — IDE сгенерирует сама.


                      В наследнике хочешь написать что-то в construct?

                      Ну, это вообще не очень нормально. Composition over inheritance, Abstract or final.


  1. uralmas
    02.05.2018 19:04
    +1

    Согласен со многими пунктами. Сам собираю список того, чтобы я изменил в PHP — с кучей новых возможностей, разделением и оптимизацией стандартной библиотеки, упрощением синтаксиса, с цепочками функций стандартных функций, без оглядки на историческое наследие.
    Но это получается уже новый ЯП, несовместимый с PHP, но конвертируемый в/из него.
    Может, как-нибудь оформлю свои заметки в статью


  1. VolCh
    02.05.2018 19:25
    +1

    Отключение возможности неявного преобразования типов. Или, хотя бы, deprecated сообщения о его использовании.


  1. Goodkat
    02.05.2018 20:05
    +2

    А что вам мешает сделать объектные обёртки для примитивов, как в JavaScript?
    ArrayObject уже давно есть.


    1. VolCh
      02.05.2018 21:09

      Дорого и ужасно выглядит что-то вроде (new String("1,2,3"))->explode(",")->map(function (string $item) { return (new String($item))->intval();});


      1. Goodkat
        02.05.2018 23:14

        Зато ж красота!


        И без new, есть же __invoke(). И это же php, intval не нужен, ну или в explode вторым параметром EXPLODE_CASTING_TYPE_INTEGER — придерживайтесь стиля phр ;-)


  1. Shamanische
    02.05.2018 20:28
    -2

    Скоро линии развития PHP и Java сойдутся в одной точке пространства-времени. Но покуда жизненный цикл PHP скрипта будет 'выполнил задачу или запрос и сдох' по-насоящему лучше он не станет.


    1. oxidmod
      02.05.2018 20:32
      +4

      Для своих целей PHP is good enough.
      А те вещи, которые действительно дорого поднимать можно запустить в виде демона, или вообще написать на другом, более подходящем языке.


      1. Shamanische
        02.05.2018 22:38

        Границ у этих, так сказать, целей нет. В этом весь фокус. Достигнув простой цели, планка требований поднимется выше, потом ещё выше, и ещё… а потом бах и OutOfMemoryException, например.
        Так или иначе язык ограничен (любой язык), а задачи — нет. Так может разработчикам PHP пора начать делать что-то более серьезное чем добавление сахара из других языков? Начать с таймера и многопоточности, вот тогда язык станет языком вне конкуренции, а не темой для холиваров.


        1. springimport
          03.05.2018 15:59
          +2

          За несколько последних лет с миграцией с 5.5 до 7.2 получил нереальное ускорение. Это что, не прогресс?


    1. kuftachev
      03.05.2018 09:58
      +4

      В этом и есть его крутость.
      Вот представь, поднять на той же Java на одном сервере 100 сайтов, или 1000, или ещё больше. В PHP если на каждой из них нет большой нагрузки все ограничено дисковыми пространством, а Java будет стартовать каждый и держать все программу в памяти.


      Есть две Java (ещё C#), есть два Python (второй Ruby), а PHP реально имеет свою нишу, в которой он незаменим.


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


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


      1. Shamanische
        03.05.2018 12:49

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


        1. kuftachev
          03.05.2018 13:02

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


          Большинство веба — это по сути CRUD, узелок место — это походы в бд, а те жалкие проценты, которые мог бы ускорить компилируемый язык, редко когда нужны (ну и есть модули на Си, и вершина развития этой идеи — Phalcon).


          А вот из скриптовых языков PHP на голову выше всех конкурентов, кроме Groovy(но там JVM и все прелести выяснения отношений с каким-то Tomcat). А Python и Ruby рядом не стоят.


  1. unfapable
    02.05.2018 21:11

    Неявное временное преобразование примитива в объект

    Вы же понимаете, что это будет совершенно другой тогда ЯП? Смущает даже более формулировка "неявное временное", в Python и Ruby, скриптовых языках, к коим относится и PHP, всё представляет из себя объекты, смысл делать из PHP очередной Ruby, это противоречит его концепции? Безусловно, профит есть, но это уже полностью изменить язык, даже если учесть что это "временно"...


    1. Короткий синтаксис функций

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


    1. Убрать function

    Вот снова отсылка к JavaScript. Однако довольно странно это выглядит, в тех же упомянутых скриптовых языках, есть ключевое слово def для объявления функции, в PHP — это function. А вообще не стоит забывать, что PHP — мультипарадигмальный язык, где кроме поддержки ООП, есть и функциональная парадигма, в отличие от Java, а в JS — классы, как известно, синтаксический сахар, так что поэтому и нет лишнего ключевого слово. В общем, плохой, я бы даже назвал, рекомендацию убирать это, смотрится не очень, даже если учитывать, что это будет опциональная фишка, с целью не писать дополнительно 8 букв, находясь внутри контекста объекта...


    1. Навести порядок

    Многое сказано правильно, но json_encode -> Json::encode, вообще жутко, да и представить себе сложно уже, т.к. кажется, что это пользовательский класс Json со статическим методом encode, а не что-то родное от языка. Да и опять же, статические вызовы в данном случае смотрятся ужасно.


    Дженерики, декораторы асинхронность — лайк, и это реально можно, если уж не реализовать (хотя всё можно, конечно), то представить себе в контексте такого языка, как PHP, однозначно.


    1. uralmas
      02.05.2018 21:33
      +2

      На мой взгляд, json_encode -> Json::encode — очень хорошая замена, т.к. в стандартных библиотеках, коей является библиотека json, все функции, свойства константы идут с префиксом от наименования библиотеки, что иногда затрудняет чтение кода (не в случае json, конечно).
      Зато все константы JSON_*, которые идут в этой библиотеке, можно будет вызывать не из глобального пространства, а как константы класса JSON
      Вообще, как многие справедливо ругают, в PHP слишком много функций находится в глобальном пространстве. Кроме этого, данная замена позволит гибко управлять и переопределять эти функции.


      1. unfapable
        02.05.2018 22:30
        +1

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


        1. rjhdby
          02.05.2018 22:52

          Нет, это не ваша проблема.
          В PHP функции стандартной библиотеки являются интринсиками (не уверен в корректности термина применительно к PHP, но по смыслу ближе всего) и работают с примитивными типами:

          _zend_value{
              zend_long         lval;  //int64_t
              double            dval;
              zend_string      *str;  //uchar
          ...
          }


          В случае объекта — это дополнительные накладные расходы на создание и хранение этого самого объекта.


          1. uralmas
            03.05.2018 10:10

            Т.к. это расширение, данный объект создаётся 1 раз при запуске php. Расходы на хранение не такие уж и большие.
            Если сравнивать варианты выполнения функции:
            1. json_encode: найти в локальном пространстве функцию json_encode, если в нём не найдём (что скорее всего и будет), ищем её в глобальном пространстве.
            2. JSON::encode: найти класс JSON, затем в нём найти статический метод encode.

            Мне кажется, что 2-ой способ будет выполняться быстрее. Могу ошибаться, не знаток внутренностей PHP.


            1. sumanai
              03.05.2018 10:14

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


            1. rjhdby
              03.05.2018 10:32

              1. Т.к. это расширение, то мы уже имеем увеличение вермени от получения запроса до начала его обработки, так как его надо загрузить и подготовить. Ну это я чисто придраться.
              2. Для JSON::encode разрешение имен будет идти абсолютно по такому же пути — сперва будет происходить поиск класса JSON в локальном пространстве имен, а потом в глобальном.


              1. uralmas
                03.05.2018 10:49

                1. Нет, загрузка расширения (и его классов) идёт всего 1 раз во время поднятия PHP (или инстансов php-fpm), а не на каждый запрос.
                2. На мой взгляд, код \JSON::encode выглядит гораздо гармоничней, чем \json_encode. Но это чисто моё мнение.

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


                1. rjhdby
                  03.05.2018 11:05

                  1. Вот хорошая статья про жизненный цикл PHP
                  2. Да я, собственно, не против. PHP позиционируется как мультипарадигменный язык. Кому-то нравится ООП, кому-то процедурный стиль.

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


        1. uralmas
          03.05.2018 10:21

          А чем в глобальном плане различаются «встроенные возможности» от сторонних библиотек? В самих встроенных библиотеках вообще можно найти разброд и ахтунг.
          Например, встроенное расширение intl. Если зайти на страницу документации php.net/manual/ru/book.intl.php и почитать названия методов, то волосы встают дыбом — смесь CamelCase, слитное написание наименований без заглавных букв, «стандартное» наименование функций прописными буквами, разделённые нижним подчёркиванием. Плюс дублирование многих функций в процедурном стиле (функции вызываются из загруженного глобального пространства) и ООП.
          В то время, как сторонние библиотеки (далеко не все, конечно) стараются держаться ООП либо вызова статических методов.


          1. rjhdby
            03.05.2018 10:49

            А чем в глобальном плане различаются «встроенные возможности» от сторонних библиотек?

            Из этой фразы стоит убрать слово "сторонних".
            В PHP есть стандартная библиотека, содержащаяся вот прямо внутри исходного кода PHP, куда входит не такое уж и большое количество функций.
            Все остальное подключается с помощью библиотек расширений — это то, что лежит в каталоге ext и включается в php.ini


            (библиотеки PECL отличается от "стандартных библиотек" только тем, что они не доступны "из коробки" и подключать/компилировать их нужно самостоятельно)


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


            1. uralmas
              03.05.2018 11:09

              Под «глобальным» я имею только их выполнение, а не способ подключения.
              JSON — та же библиотека, только «вшитая» в ядро. Я не про неё конкретно. Есть достаточно много таких «вшитых» библиотек, некоторые из которых можно отключить при компиляции.
              Так что в глобальном плане они не отличаются от сторонних. Только образование наименований функций отличается. И это порой создаёт путаницу.
              Понимаю, что это из-за наследия формирования PHP, и что это не изменить. Но такая разнородность «не красит» язык.
              Всё написанное прошу считать моими «мысли вслух». Это просто тезисы моего ЯП, который я создаю на основе PHP, существующий только в моей голове.


              1. rjhdby
                03.05.2018 11:42
                +1

                Видимо я не совсем понятно объяснил.
                В PHP нет "вшитых" библиотек кроме standard, которую нельзя отключить. И, в частности, практически все функции работы с однобайтовыми строками содержатся именно в ней.


                Все, что можно отключить/подключить — является библиотеками, которые довольно условно делятся на два типа — те, которые включены в поставку (например mbstring или json) и те, которые PECL.


  1. rjhdby
    02.05.2018 21:21

    Многое из перечисленного уже есть на wiki.php.net/rfc в качестве предложений.
    Про многопоточность в каждом еженедельном дайджесте про PHP на хабре есть отсылки.
    если убрать слово `function`, то, насколько я понимаю, сильно усложнится процесс токенизации, что печально скажется на производительности. Да и не факт, что без жестко поломанной обратной совместимости не обойдется, если вдруг.


  1. moscowman
    02.05.2018 22:13

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


    1. jehy
      03.05.2018 08:29

      «другая сторона» — это индийский аутсорс, что ли? Или эффективный менеджмент?


  1. Samouvazhektra
    02.05.2018 22:25

    Да, сахарка со стрелочными функциями очень хотелось бы, а если это еще приправить штукой типа https://github.com/sebastiaanluca/php-pipe-operator c поддержкой из коробки, будет совсем замечательно
    Ну и про порядок с array_map/array_filter etc. и со строковыми функциями конечно тоже наболело, понятно что оберток хватает, но и нативных подвижек хотелось бы


    1. Samouvazhektra
      02.05.2018 22:31

      И еще, если не дженерики, то хотябы в phpdoc описание структуры массива


      array[<string>, <int>], array[<int>, SomeClass[]]


    1. rjhdby
      02.05.2018 22:38

      Ну и про порядок с array_map/array_filter etc. и со строковыми функциями конечно тоже наболело

      Малейший чих в сторону изменения поведения/порядка аргументов в функциях стандартной библиотеки PHP равносилен развязыванию маленькой ядерной войны — вроде и маленькая, но трясти и корёжить будет весь мир. Ситуация, конечно, очень печальная и, как мне кажется, решением может быть только создание параллельной стандартной библиотеки с постепенной (через 3-4 мажорных релиза) деприкацией старой.


      1. Goodkat
        02.05.2018 23:32
        +1

        Можно было упрятать все эти старые стандартные функции в какой-нибудь namespace и пометить как deprecated и сделать им модные современные алиасы с однотипным наименованием функции и порядком аргументов.
        Кто хочет пользоваться старыми для поддержки legacy, тот подключает namespace legaсу, а остальные переходят постепенно на новые, причём этот переход можно было бы почти полностью автоматизировать средствами самого языка.
        Я думал, что так и сделают с введением namespace.


        1. rjhdby
          02.05.2018 23:49

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


          1. Goodkat
            03.05.2018 00:22

            Как раз не ломает же. Старые функции помечаются как deprecated, но работают.


            1. rjhdby
              03.05.2018 00:53

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

              function strstr($a){
                  echo $a;
              }

              И всё заверте…

              Пример конечно утрированный, но нарушение обратной совместимости демонстрирует.


              1. Goodkat
                03.05.2018 01:59

                Это будет уже новый код, от выстрелов в ногу везде защиту не поставишь.
                И да, такое поведение иногда даже желательно, можно делать так:
                `function strstr($a){
                log();
                return legacy\strstr($a);
                }


        1. symbix
          03.05.2018 00:37

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


          Имеет смысл добавить ООП-варианты вида $array->map(...)->reduce(...) / $string->length(), а функции оставить как были для обратной совместимости.


          1. m0rtis
            03.05.2018 10:54

            На php куча кода, который поддерживать вообще некому, просто работает и работает.

            Тогда там и версию PHP некому будет обновить, а значит ничего не сломается:)


            1. symbix
              03.05.2018 16:22

              А оно с обновлениями серверов ломается. Какой-нибудь Pentium 4 с Debian Etch не вечен. :-)


              Мне вот до сих пор для старого кода приходится держать PHP 5.3, например, и только потому, что придумали сломать call_by_ref в идиотской манере. Причем, если таки сделают explicit_send_by_ref, — а это именно то, как call by ref
              в этом старом коде используется — можно будет сразу ставить 7.3 (или что там будет) — все должно завестись (разве что для совсем-совсем старого кода времен php4 понадобится полифилл на ext/mysql).


    1. symbix
      02.05.2018 23:29

      array_map/array_filter

      Тут порядок легко запомнить:


      • у array_map varargs, чтобы скормить несколько массивов,
      • array_filter можно использовать без второго аргумента, что идентично function($v) { return !!$v; }.

      Вот со строковыми функциями сложнее, впрочем, IDE всегда подскажет :-)


  1. richtrr
    02.05.2018 23:58
    -4

    image

    А магнитные полюса земли в ближайшее время…
    Как бы это вам сказать…
    Магнитные полюса… знаете ли…

    Не изменятся.


    1. Fesor
      03.05.2018 13:27

      в ближайшее время

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


  1. poxvuibr
    03.05.2018 00:59

    По какой-то необъяснимой причине в статье отсутствует предложение убрать необходимость ставить значок доллара перед переменной. По той же необъяснимой причине ничего не сказано про то, что было бы лучше, если бы к полям объекта можно было обратиться не через два символа ->, а через какой-нибудь один символ.


    А ведь, казалось бы, очевидные кандидаты на улучшение.


    1. kuftachev
      03.05.2018 03:05

      Конечно, меня это тоже бесит, но на счёт $ под точно проблема вылезет в том, что в строке "..." не понятно как искать переменную. Это то, что на поверхности, может ещё какие-то трудности.


      А по -> — это переписать весь существующий код на PHP, и это не Java, где что-то скомпилировать можно и старым компилятором, тут вообще все умножится на ноль. В Плюсах с этим как-то живут.


      1. yarosroman
        03.05.2018 05:14

        В других языках как-то без $ обходятся. И в плюсах между. и -> есть разница.


        1. kuftachev
          03.05.2018 09:07
          +1

          Вообще-то я не говорил, что без этого нельзя сделать язык, я говорил, что это сломает слишком много кода.


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


        1. rjhdby
          03.05.2018 10:18

          Допустим отказались от знака доллара. Как токенизатору толковать вот такую строку?

          a();

          Вызов функции `a`?
          Вызов метода `__invoke()` у класса, хранящегося в переменной `a`?
          Вызов функции, имя которой хранится в переменной `a`?
          Еще как-то?


          1. poxvuibr
            03.05.2018 13:56

            Вызов функции a?
            Вызов метода __invoke() у класса, хранящегося в переменной a?

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


            Вызов функции, имя которой хранится в переменной a?

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


            1. rjhdby
              03.05.2018 14:08
              +1

              или придумать другое однозначно трактуемое правило.

              Например однозначное определение переменной с использованием символа $


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


              1. poxvuibr
                03.05.2018 15:18
                -1

                или придумать другое однозначно трактуемое правило.
                Например однозначное определение переменной с использованием символа $

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


                Описываемое вами поведение, когда у a() может означать вызов функции, а может означать вызов метода у объекта, который хранится в переменной a, присутствует в C++ и, если программистам на C++ предложить ради упрощения разруливания этого кейса ставить значок доллара перед каждой переменной, они просто покрутят пальцем у виска.


                Особенно странно заниматься этим из-за оскорбленного эстетического чувства довольно малой части разработчиков.

                Эстетика тут не при чём. Набирать $ перед каждой переменной объективно неудобно и в этом объективно нет необходимости.


                1. rjhdby
                  03.05.2018 16:16
                  +1

                  если программистам на C++ предложить

                  Зачем вы пытаетесь сравнивать ежа и ужа?


                  Сходите к перловикам и расскажите, что ажно три разных префикса для переменных — это неудобно.
                  Сходите к дельфистам и расскажите, что := — это трешь.
                  Сходите к сишникам и объявите, что от вездесущих * и & в глазах рябит.
                  Поведайте питонщикам, что выделять блоки кода отступами — это за гранью добра и зла.
                  Расскажите создателям Kotlin, что типы должны быть слева, потому что вы в Java так привыкли.
                  они просто покрутят пальцем у виска.©


                  Синтаксис любого языка вырабатывается с конкретными целями. У использования доллара как префикса переменной в PHP есть конкретная цель — однозначное определение переменной в коде. А нужно это для:


                  1. Облегчения чтения кода. Вы ведь помните, что 80% времени разработчик именно читает код?
                  2. Ускорение работы парсера. Для PHP по сути его критично время старта.


                  1. poxvuibr
                    04.05.2018 23:23
                    -1

                    Зачем вы пытаетесь сравнивать ежа и ужа?

                    Я не пытаюсь делать ничего такого. Вы декларируете, что ставить доллар перед каждой переменной лучше, чем ввести правила, по которым будет определяться является a функцией или переменной. Я в ответ пишу, что в языке программирования, в котором фича с долларом отсутствует — никто не спешит её добавлять. Почему-то вместо этой, по вашему мнению разумной альтернативы, комитет по развитию С++ предпочитает ввести правило. Мне кажется, вы попали в ловушку рационализации недостатков инструмента, которым вы пользуетесь и хочу сказать, что в языках, в которых недостатка, который вы считаете фичей, нет — никто не спешит его добавлять. Возможно именно потому, что это недостаток.


                    Теперь по пунктам про приведённые вами утверждения


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

                    Неудобно, но в перле эти префиксы хотя бы нужны для раделения типов переменных.


                    Сходите к дельфистам и расскажите, что := — это треш.

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


                    Сходите к сишникам и объявите, что от вездесущих * и & в глазах рябит.

                    Вот тут вы собственноручно приступили к сравнению ежа с ужом. У символов * и & в Си есть смысл, убрать их просто так невозможно.


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

                    Я только что объяснял, что в лишнем символе перед переменными нет необходимости. Странно будет, если я сразу после этого буду говорить, что, хотя отступов достаточно для выделения блоков кода, обязательно надо выделить блоки чем-то ещё.


                    Расскажите создателям Kotlin, что типы должны быть слева, потому что вы в Java так привыкли.

                    Опять сравнение ужа с ежом — с какой стороны объявлять тип переменной — в основном дело вкуса. Объективных аргументов за или против тут нет.


                    1. rjhdby
                      04.05.2018 23:46

                      [промахнулся]


                  1. poxvuibr
                    04.05.2018 23:34

                    Синтаксис любого языка вырабатывается с конкретными целями.

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


                    Облегчения чтения кода. Вы ведь помните, что 80% времени разработчик именно читает код?

                    В IDE можно подкрасить переменную любым интересным вам цветом. Также IDE подкрашивает переменные в зависимости от дополнительных факторов. Знак доллара облегчает чтение кода только если вы используете какой-то текстовый редактор типа Блокнот.


                    Ускорение работы парсера. Для PHP по сути его критично время старта.

                    Ну это даже не смешно. Во-первых, существенно на время старта наличие или отсутсвие значка доллара не влияет, во-вторых те, кому это по настоящему критично — компилируют код заранее.


                    1. rjhdby
                      05.05.2018 00:13
                      +1

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

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

                      Ну это даже не смешно. Во-первых, существенно на время старта наличие или отсутсвие значка доллара не влияет, во-вторых те, кому это по настоящему критично — компилируют код заранее.
                      Во-первых — повлияет.
                      Во-вторых — это как раз критично для всех, кроме high load (для них тоже критично, но только на прогреве). А таковых подавляющее большинство. Тут на хабре были статьи про критичность времени отклика — почитайте.

                      Я в ответ пишу, что в языке программирования, в котором фича с долларом отсутствует — никто не спешит её добавлять.
                      А в языках, где присутствует — никто не спешит убирать. Вам не кажется, что это прямо про притчу о своем уставе в чужом монастыре?

                      Почему-то вместо этой, по вашему мнению разумной альтернативы, комитет по развитию С++ предпочитает ввести правило.
                      А мантейнеры PHP, почему-то, предпочитают оставить доллар. При этом они не лезут в комитет по развитию С++ с предложением все переделать как у них. Странно, правда?


                      1. poxvuibr
                        05.05.2018 00:51

                        Позвольте не поверить и попросить предоставить пруфы.

                        Ну вот, например.


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

                        То есть доллар перед переменными нужен тем, кто пользуется этими редакторами? А что это за редакторы? Можно поимённо? Вы, кстати, пользуетесь ими? Или в IDE пишете?


                        Во-первых — повлияет.

                        И, конечно, у вас есть результаты тестов? Или какие-то другие пруфы? Есть?


                        Во-вторых — это как раз критично для всех

                        Значит все должны компилировать код заранее. Это ускорит старт сильнее, чем доллары перед именами переменных.


                        А в языках, где присутствует — никто не спешит убирать.

                        И в каких языках нужно перед каждой переменной ставить один и тот же символ?


                        Вам не кажется, что это прямо про притчу о своем уставе в чужом монастыре?

                        Это не притча, это пословица :). И это пословица о том, что необходимо соблюдать установленные правила, а не о том, что их нельзя обсуждать.


                        А мантейнеры PHP, почему-то, предпочитают оставить доллар.

                        Так уж здесь заведено. О том, что можно по другому, почему-то мало кто задумывается.


                        При этом они не лезут в комитет по развитию С++ с предложением все переделать как у них. Странно, правда?

                        Да и члены комитета по развитию С++ не лезут к майнтейнерам PHP с предложением всё переделать как у них. Вас это тоже удивляет?


                        1. rjhdby
                          05.05.2018 01:36

                          Ну вот, например.
                          Источник так себе, но да ладно. Вопрос на засыпку — какой процесс облегчается в результате «an ability to insert variables inside literal string values»? Не парсинг ли?

                          А что это за редакторы? Можно поимённо? Вы, кстати, пользуетесь ими? Или в IDE пишете?
                          Например vi и notepad++. Постоянно пользуюсь обоими, хотя имею опенсорсную лицензию на все продукты JetBrains. (нет, notepad++ НЕ обладает развитыми возможностями подсветки синтаксиса. vi тем более)

                          И, конечно, у вас есть результаты тестов?
                          А у вас? У меня есть опыт написания расширений к PHP, ковыряния в его коде и изучения принципов работы.

                          И в каких языках нужно перед каждой переменной ставить один и тот же символ?
                          Perl. Перед каждой переменной конкретного типа ставится фиксированный префикс. В PHP тип один — ```zend_value```

                          О том, что можно по другому, почему-то мало кто задумывается.
                          Не, ну кто бы спорил. Все вокруг дураки. Слава богу один умный нашелся и всем глаза раскрыл.

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

                          Вишенка на торте.
                          Как я уже писал, надо компилировать заранее, а не затачивать синтаксис под нужды компилятора.
                          А что еще все должны делать?
                          Вам не кажется, что это несколько странное пожелание для интерпритируемого языка? (дабы избежать лишней итерации переписки — я пишу на Java, Kotlin, PHP, C, Objective C и чутка на ассемблере — для души)


                          1. poxvuibr
                            05.05.2018 02:11

                            Вопрос на засыпку — какой процесс облегчается в результате «an ability to insert variables inside literal string values»? Не парсинг ли?

                            Он самый. Но можно ставить доллар перед переменными только внутри строк. Везде их ставить необходимости нет.


                            (нет, notepad++ НЕ обладает развитыми возможностями подсветки синтаксиса. vi тем более)

                            Во-первых у vim возможности подсветки получше, чем у notepad++, а во-вторых подсветки и того и другого хватает, чтобы выделить всё, кроме собственно переменных. Для того, чтобы проблемы появились, надо использовать notepad.


                            У меня есть опыт написания расширений к PHP, ковыряния в его коде и изучения принципов работы.

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


                            Perl. Перед каждой переменной конкретного типа ставится фиксированный префикс.

                            Этих префиксов несколько. Поэтому, что один и тот же символ нужно ставить перед каждой переменной, сказать нельзя.


                            Тем более странно, что лезете вы и потрясаете их комитетом.

                            Странно, что вас удивляет, что я написал, как можно улучшить PHP в статье про то, как можно улучшить PHP. Так же очень странно, что вы охарактеризовали мои слова как "потрясание комитетом", да и то, что вы вообще написали, что майнтейнеры не лезут с советами к комитету по развитию С++ очень странно. Создаётся впечатление, что вы воспринимаете выражение моей позиции как попытку покуситься на что-то сакральное.


                            А что еще все должны делать?

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


                            Вам не кажется, что это несколько странное пожелание для интерпритируемого языка?

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


                            1. rjhdby
                              05.05.2018 02:30

                              Во-первых у vim… во-вторых подсветки и того и другого хватает...
                              Во-первых не vim, а vi.
                              Во-вторых — подсветки хватает, пока парсер редактора может однозначно определить переменную. Когда он этого сделать не может, то и подсветка начинает уже не помогать, а мешать. Даже у Idea бывает крышу сносит на, вроде бы, «правильных» языках, что уж говорить о других редакторах.

                              А для доказательства вашего утверждения
                              Начнем с того, что это именно вы утверждаете, что никак не скажется. Извините, но в случае парсера ЯП доказывать отсутствие импакта должен предлагающий изменения.

                              Поэтому, что один и тот же символ нужно ставить перед каждой переменной, сказать нельзя.
                              Перед каждым скаляром надо ставить $. Перед каждой хэш-таблицей надо ставить %. Перед каждым массивом надо ставить @.

                              Странно, что вас удивляет, что я написал, как можно улучшить PHP в статье про то, как можно улучшить PHP.
                              Меня удивляет, что в статье про то, как можно улучшит PHP, вы предлагаете переделать его в С++. Не более того. Спасибо — не надо. Когда мне нужен С++ — я пользуюсь им, но когда мне нужен PHP, то и беру я PHP.

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


                              1. poxvuibr
                                05.05.2018 03:02

                                Во-первых не vim, а vi.

                                Либо вы на своём компьютере по какой-то причине используете vi вместо vim, что удивительно, либо редактируете код на какой-то удалённой машине, что объясняет, например, ваше нежелание компилировать код. Вам в вашей ситуации, возможно, действительно имеет смысл именовать все переменные как-нибудь особенно, например начинать с доллара. Но делать это обязательным для всех нецелесообразно.


                                Начнем с того, что это именно вы утверждаете, что никак не скажется.

                                Началось всё с вашего утверждения о том, что скажется, причём скажется существенно.


                                Перед каждым скаляром надо ставить $. Перед каждой хэш-таблицей надо ставить %. Перед каждым массивом надо ставить @.

                                Да, перед разными видами переменных надо ставить разные префиксы. Поэтому утверждение, что в Perl перед всеми переменными нужно ставить один и тот же символ — ложно.


                                Меня удивляет, что в статье про то, как можно улучшит PHP, вы предлагаете переделать его в С++.

                                Это неправда, я этого не предлагал.


                                То, что мотоцикл имеет два колеса и может упасть на бок(пока не едет) не означает, что нужно приделать ему еще два и превратить его в машину.

                                Поясните, пожалуйста, что вы хотели этим сказать.


                                1. rjhdby
                                  05.05.2018 03:38

                                  что объясняет, например, ваше нежелание компилировать код
                                  :facepalm:
                                  Вы понимаете, что PHP — это скриптовый (интерпритируемый) язык? Что он потому и подходит для решения определенного скопа задач именно потому, что его не надо компилировать?

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

                                  Да, перед разными видами переменных надо ставить разные префиксы. Поэтому утверждение, что в Perl перед всеми переменными нужно ставить один и тот же символ — ложно.

                                  В PHP не перед всеми переменными и не всегда надо ставить символ $. Сталобыть ваше утверждение также ложно.

                                  Это неправда, я этого не предлагал.
                                  Именно к этому вы и ведете. Сначала вы предлагаете убрать $, аргументируя, что С++ обходятся без него. Потом начали рассказывать про компиляцию. Это все здорово, но непонятно, причем тут PHP?

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


                                  1. poxvuibr
                                    05.05.2018 11:16

                                    Вы понимаете, что PHP — это скриптовый (интерпритируемый) язык?

                                    Понимаю.


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

                                    Да, но с ваших слов веб к этим задачам не относится, потому что всем надо делать так, чтобы скрипт стартовал как можно скорее. Самый лучший способ это сделать — компилировать заранее.


                                    В PHP не перед всеми переменными и не всегда надо ставить символ $. Сталобыть ваше утверждение также ложно.

                                    То есть, если доллара нет, то нельзя точно сказать, что перед нами не переменная? И в каких случаях не нужно ставить доллар перед переменными?


                                    Именно к этому вы и ведете.

                                    Нет, не веду.


                                    Сначала вы предлагаете убрать $, аргументируя, что С++ обходятся без него.

                                    Мой аргумент — необходимости в долларе нет и другие языки прекрасно это демонстрируют. Вместо С++ можно взять какой-нибудь другой пример.


                                    Потом начали рассказывать про компиляцию.

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


                                    Это все здорово, но непонятно, причем тут PHP?

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


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

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


                        1. Vilgelm
                          05.05.2018 04:10

                          То есть доллар перед переменными нужен тем, кто пользуется этими редакторами?

                          Мне нужно внести какие-то небольшие изменения в код или посмотреть на строку, в которой возникает ошибка. Я подключаюсь по ssh, ввожу nano name.php или vi name.php и читаю код. А вы мне предлагаете IDE ставить. На сервер. Который бы в консоли работал. Мне почему-то сразу хочется послать в известном направлении с такими предложениями.


                          1. oxidmod
                            05.05.2018 08:36

                            Ну… Так то IDE умеют в удаленное подключение.


                    1. rjhdby
                      05.05.2018 00:49

                      Почему повлияет (не про высоконагруженные, где opcache и прочие).
                      Операция компиляции происходит при каждом(!) выполнении скрипта. Эта задержка, какой бы малой она не была, добавится ко времени отклика вообще каждого скрипта. Это как раз тот случай, когда экономия на спичках оправдана.

                      Если рассматривать средней сложности приложение с десятком подгружаемых классов — умножай на количество подгружаемых файлов.

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


                      1. poxvuibr
                        05.05.2018 00:54
                        -1

                        Операция компиляции происходит при каждом(!) выполнении скрипта. Эта задержка, какой бы малой она не была, добавится ко времени отклика вообще каждого скрипта. Это как раз тот случай, когда экономия на спичках оправдана.

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


                    1. VolCh
                      05.05.2018 18:05

                      > Знак доллара облегчает чтение кода только если вы используете какой-то текстовый редактор типа Блокнот.

                      Или просматриваете где-то на гитхабе. Или книгу читаете.


                      1. poxvuibr
                        05.05.2018 18:59

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


                1. springimport
                  03.05.2018 16:19

                  Мне в js наоборот странно когда возле переменной ничего нет, а набирание постоянных let вообще напрягает.
                  И вообще, если $ все не замечают и никого не напрягает — значит знак выбран удачно. Конечно, кому-то может и не зайти. Я все жду когда для php появятся свой babel и тогда заживем. И вы сможете не писать $)


        1. NickyX3
          03.05.2018 16:01

          А в некоторых не только не обходятся с $, но еще и @# юзают… Для переменных :-)


      1. poxvuibr
        03.05.2018 13:40

        на счёт $ под точно проблема вылезет в том, что в строке "..." не понятно как искать переменную

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


        А по -> — это переписать весь существующий код на PHP, и это не Java, где что-то скомпилировать можно и старым компилятором, тут вообще все умножится на ноль

        Я бы предложил оставить старый код как есть, а в файлах с новым кодом добавить директиву, наподобии "use strict" в javascript. При использовании этой директивы для получения поля объекта надо было бы использовать точку, а для конкатенации какой-нибудь другой символ. Можно даже ->, лично у меня возражений нет :). Но лучше, конечно, какой-нибудь один символ.


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


        1. springimport
          03.05.2018 16:24

          Проблему -> решила бы клавиатура с настраиваемыми клавишами.


        1. kuftachev
          03.05.2018 18:09

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


    1. Goodkat
      03.05.2018 09:14
      +1

      Вы, наверное, и переменные называете a, b и с, чтобы сэкономить?


      1. poxvuibr
        03.05.2018 13:50

        Нет, не называю :). Когда экономия создаёт объективные проблемы — лучше не экономить. Но значок доллара перед каждой переменной смысловой нагрузки не несёт и, если его убрать, хуже не станет.


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


    1. m0rtis
      03.05.2018 11:00
      +1

      Лично мне (подчеркиваю эти два слова) знак доллара перед именем переменной гораздо удобнее — и с точки зрения читаемости, и с точки зрения всяких фишек типа подстановки значения переменной в строках в двойных кавычках. Не вижу ни малейшего смысла знак доллара убирать.
      А вот насчет точки вместо стрелочки — оно можно, но ничего хорошего (в отличие, например, от дженериков) в язык это не принесет. А вот с конкатенацией и оператором ".=" будут проблемы. Так что пусть уж лучше будет привычная стрелочка:)


      1. poxvuibr
        03.05.2018 13:58

        Лично мне (подчеркиваю эти два слова) знак доллара перед именем переменной гораздо удобнее — и с точки зрения читаемости

        Если есть IDE, она подсветить переменные каким-нибудь цветом. Если без IDE, то знак доллара действительно приносит определённую пользу.


        и с точки зрения всяких фишек типа подстановки значения переменной в строках в двойных кавычках

        Эту функцию знака доллара можно оставить.


    1. dmitryklerik
      03.05.2018 11:41
      +3

      Значок $ перед переменными это очень удобно для того чтобы отличать переменную от функции и это как раз выгодно отличает php от многих других языков


      1. IvanNochnoy
        03.05.2018 14:25

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


        1. sumanai
          03.05.2018 14:30

          На JS походу так делают только для объектов JQuery, на остальных и вовсе не замечал.


  1. yarosroman
    03.05.2018 02:15

    В C# все это давно есть.


    1. m0rtis
      03.05.2018 11:08
      +1

      А в бейсике нужно нумеровать строки десятками. И что, какое это отношение имеет к будущему PHP?


      1. vlreshet
        03.05.2018 11:51

        Разве не любыми числами? По-моему, десятками было просто общепринято, типа кодстайл)


        1. m0rtis
          03.05.2018 12:00

          Разве не любыми числами? По-моему, десятками было просто общепринято, типа кодстайл)

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


        1. rjhdby
          03.05.2018 12:02

          Да и не в любом бейсике нумерация нужна, если уж на то пошло.

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


  1. kuftachev
    03.05.2018 02:54

    Ещё нужно знак доллара поменять на знак евро, ну или рубля.


    В общем, завязывайте со спиртным ;-)


    1. springimport
      03.05.2018 16:33
      +3

      Так и представляю: где-нибудь в php.ini

      ; Okay, guys, now you can choose your favorite currency
      ; $variable
      ; €variable
      ; ?peremennaya
      developer.loved_currency_symbol = $


  1. VolCh
    03.05.2018 05:18

    Вот ещё вспомнилось: autoload для функций


  1. alexkbs
    03.05.2018 06:53

    Функции, работающие с массивами, не меняют исходный массив, за некоторым исключением. Вы считаете что методы вида $arr->map(...) и $arr->filter(...) должны следовать исходной семантике, или должны менять исходный массив, на котором они вызываются?


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

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


    1. kuftachev
      03.05.2018 09:20

      Ну как они могут менять? Это же элементы функционального программирования, там вообще ничего не меняется.


    1. VolCh
      03.05.2018 09:39

      Есть RFC о иммутабельных объектах, тут они очень в тему будут. Но, вероятно, для эффективной работы нужны будут оптимизации как раз чтобы не делать clone на каждую операцию.


      1. alexkbs
        03.05.2018 09:47

        Признаться честно даже если такие массивы будут иммутабельные, это нисколько не сделает PHP как язык лучше, а наоборот — сделает работу с массивами ещё сложней и запутанней, чем она уже есть.


        Например, сейчас ты вызываешь функцию и получаешь результат. Плохая или хорошая функция, всё очень понятно и однозначно.


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


        1. VolCh
          03.05.2018 09:53

          С результатом сейчас не всё однозначно, даже если ограничиться семейством функций array_*.


          1. alexkbs
            03.05.2018 09:54

            Не обязательно однозначно, но предсказуемо. Достаточно запомнить как работает конкретная функция, не нужно держать в голове ещё какие-то концепты.


            1. VolCh
              03.05.2018 11:32

              Тут достаточно будет запомнить одно правило: применение оператора -> к скаляру или массиву всегда будет возвращать новое значение, а не менять существующее.


              1. alexkbs
                03.05.2018 11:48

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


    1. T-362
      03.05.2018 12:29

      В принципе, можно используя немножко черной магии сделать как-то так уже сейчас:

      $b = Array::asort($a, SORT_REGULAR); // получаем новый массив
      $a->asort(SORT_REGULAR); // меняем имеющийся массив
      

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


      1. springimport
        03.05.2018 16:39

        Всегда выше переменной можно написать пояснение:

        /** @var \Class $item */
        $item->get();
        


  1. impwx
    03.05.2018 11:12
    +2

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

    Язык может быть востребован по нескольким причинам: он предлагает уникальное решение для некой задачи, или же имеет большую кодовую базу. Изначально PHP опирался на первый пункт и был самым простым языком для написания веб-страниц, но тогда веб был совсем другим: никто не заботился о безопасности и поддерживаемости, важнее всего была возможность что-то слепить по-быстрому. Именно поэтому в языке изначально были такие секьюрити-дыры, как register_globals и magic_quotes_gpc. Теперь же удобных для бэкенда языков не меньше дюжины, но у PHP остается преимущество в виде огромного числа написанных на нем приложений и специалистов разного уровня.

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

    В отличие от фронтенда, где исторически существует только JS, на бэкенде есть огромный выбор. Почти всем пожеланиям автора отвечают, например, уже существующие Typescript/C#/Java 8. Не стоит зацикливаться на одном инструменте, когда требуемую задачу лучше решает другой.


    1. VolCh
      03.05.2018 11:37

      Ну, у PHP останется, как минимум, его модель выполнения в самом популярном случае использования. Да и изменения можно вводить постпенно, не ломая BC сразу, а делая некоторые фичи сначала просто нерекомендуемыми, потом deprecated, а уж потом выпиливать совсем. Например, в 8.0 добавить новое, а существующее на уровне документации объявить нерекомендуемым, в 9.0 сделать deprecated, в 10.0 выпилить.


      1. vtvz_ru Автор
        03.05.2018 13:03

        Можно старые функции оставить, пометить как deprecated, а новое по-человечески запихивать в namespace'ы, а не в глобальную область видимости


        1. rjhdby
          03.05.2018 16:26

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

          private static function parseMethodName($token): string {
              return trim(strrchr(rtrim($token, "\n\r\t */"), ' '));
          }

          Превратится в такое, например :)
          private static function parseMethodName($token): string {
              return standard\string\trim(standard\string\strrchr(standard\string\rtrim($token, "\n\r\t */"), ' '));
          }


          1. vtvz_ru Автор
            03.05.2018 17:14

            Любые функции можно импортировать через use, как и классы. Поэтому, это опять же не проблема.


            1. rjhdby
              03.05.2018 17:34

              Вы можете объективно описать недостатки присутствия этих функций в конревом пространстве имен?


            1. rdifb0
              05.05.2018 12:37

              Ага, а потом список импортов занимает пол файла.


              1. Fesor
                05.05.2018 14:03

                если так — то может стоит задуматься почему у вас такое разнообразие зависимостей используется? Ну и всегда можно сделать так:


                use function \{strlen, strpos, array_map, array_reduce};


          1. VolCh
            03.05.2018 17:20

            1. rjhdby
              03.05.2018 17:35

              Чуть выше написал. Дабы не плодить одинаковых веток.


      1. impwx
        03.05.2018 14:49

        Такими темпами «наведение порядка» растянется лет на десять. И что конкретно вы подразумеваете под «моделью выполнения»?


        1. VolCh
          03.05.2018 14:52

          Ну на каждый минорный релиз можно.

          mod_php для apache и(или) php_fpm для fastcgi


          1. impwx
            03.05.2018 15:04

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

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


            1. VolCh
              03.05.2018 17:16

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


              1. impwx
                03.05.2018 18:08

                Так практически в любом MVC-фреймворке такой же подход: для пользователя важно только то, что на каждый запрос к серверу будет создан класс-контроллер и вызван метод-действие. Более того, можно легко сделать статический кеш объектов (если очень нужно и понимаешь, что делаешь). Не вижу тут преимущества PHP.


                1. sumanai
                  03.05.2018 18:35

                  Не вижу тут преимущества PHP.

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


                  1. impwx
                    03.05.2018 19:02
                    +1

                    Для меня это скорее недостаток, и он очень в духе PHP. В данном случае у вас в логике явный баг, но система не помогает вам его найти и исправить, а наоборот маскирует его неявным поведением — до поры, до времени.

                    Знаете про принцип fail fast? Если в двух словах, то он звучит так: надежное приложение при ошибке падает и ничего не делает. PHP же всегда старается сделать хоть что-то, зачастую неправильно и, что еще хуже, молча — так вы можете потерять данные и даже не заметить этого. Там даже есть специальный оператор управления ошибками, который «затыкает» ошибки, возникающие во время вычисления выражения!

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

                    $data = json_decode(file_get_contents($cache), true);
                    update($data);
                    file_put_contents($cache, json_encode($info, JSON_PRETTY_PRINT));
                    

                    Оказалось, что скрипт был запущен в PHP 5.3, а флаг JSON_PRETTY_PRINT появился только в PHP 5.4. В результате json_encode молча вернул NULL, и даже в json_last_error ничего не было, а данные пропали.


                    1. sumanai
                      03.05.2018 19:36

                      Для меня это скорее недостаток, и он очень в духе PHP.

                      Ну значит вам для ваших задач PHP не подходит.
                      Буквально вчера у меня был случай

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


                      1. impwx
                        03.05.2018 21:57

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

                        Скрипт был изначально невалиден как минимум по двум причинам. Во-первых, идентификатор JSON_PRETTY_PRINT не был объявлен, что даже в весьма либеральном JS считается ReferenceError, но PHP предпочел молча превратить его в строку. Во-вторых, json_encode на вход был передан аргумент неправильного типа, а он молча вернул NULL. В документации, кстати, сказано, что в случае ошибки возвращается false. В обоих случаях не было даже notice!

                        Люди ошибаются. Поэтому строители носят каски, а альпинисты используют страховку. И только бесстрашные программисты продолжают писать на языках с неявными эффектами :)


                        1. oxidmod
                          03.05.2018 22:00

                          Если говорить откровенно, то PHP бросает notice при обращении к неизвестной константе.


                          1. impwx
                            03.05.2018 22:18

                            Любопытно. У меня на сервере даже с error_reporting(E_ALL) полная тишина. Правда, я использую IIS — возможно, дело в этом.


                            1. symbix
                              04.05.2018 02:35

                              А error_log вообще включен? :)


                              Вообще, стандартная практика, используемая во всех современных фреймворках — на каждую ошибку, включая notice, выбрасывать исключение. Да и без фреймворков тоже стандартная, делается в 5 строк кода.


                        1. sumanai
                          04.05.2018 06:31

                          Была проверка на ошибку

                          Никогда не помешает проверить и результат на корректность. Что NULL, что false не являются корректными данными для JSON.
                          Плюс в скрипте не указана минимальная версия для запуска.


                          1. impwx
                            04.05.2018 10:16

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


                            1. oxidmod
                              04.05.2018 11:09

                              Нет, мы приходим к тому, что надо использовать composer с указанием необходимых минимальных требований к платформе (версия пхп, екстеншены и прочее)


                              1. impwx
                                04.05.2018 11:25

                                Как это решает проблему возможной опечатки в константе?


                                1. oxidmod
                                  04.05.2018 11:34

                                  Как любой другой интерпретируемый язык спасет вас от опечатки?
                                  Ну а глобально — вменяемая IDE, тесты.
                                  В этом случае константа была корректная, но не зафиксирована версия пхп. Композер тут как раз помог бы


                                  1. impwx
                                    04.05.2018 11:44

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

                                    Python:

                                    a = b // NameError: name 'b' is not defined
                                    

                                    Javascript:
                                    a = b; // ReferenceError: b is not defined
                                    

                                    Ruby:
                                    a = B // uninitialized constant B
                                    


                                    1. oxidmod
                                      04.05.2018 11:51

                                      1. impwx
                                        04.05.2018 12:02

                                        В моих примерах заведомо некорректная программа останавливается с ошибкой, а в вашем — продолжает работать дальше. Это очень плохо.


                                        1. oxidmod
                                          04.05.2018 12:10

                                          PHP дает вам возможность гибко этим управлять.


                              1. rjhdby
                                04.05.2018 11:36

                                А если мне не по нраву стрельба из пушки по воробьям?


                            1. sumanai
                              04.05.2018 11:56

                              Причём тут вообще PHP? Для написания надёжного кода на любом языке нужен параноидальный код.


                              1. impwx
                                04.05.2018 12:06

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


                                1. sumanai
                                  04.05.2018 12:09

                                  Например С, ASM?
                                  Если уж говорить о надёжности, то нужно использовать Ada, но знаете, работу с этим языком искать трудно, всё больше JS требуют, где с этим ничем не лучше PHP.


    1. kuftachev
      03.05.2018 18:15

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


      Хорошо, что в отличии от авторов JS они хоть наркоту не употребляли ))))


  1. dmitryklerik
    03.05.2018 11:51

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


    1. impwx
      03.05.2018 14:58

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

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


  1. mr_avi
    03.05.2018 11:55

    Как по мне, PHP неплохо развивается как ОО язык, и большинство функций, констант и п.р. можно переместить в классы (json_encode -> Json::encode, cUrl).

    Можно по-быстрому набросать преобразование вызова статического метода в вызов стандартной функции, вроде этого:
    github.com/uavn/artwrap/blob/master/Art/Wrapper/Hash.php


  1. 1Tiger1
    03.05.2018 12:24
    +1

    PHP может стать еще лучше если из него сделать JS? как то так я увидел в статье, с примесью java и scala. Спасибо, не надо ассинхроности, и магии по минимуму. PHP хорош как раз своей относительной простотой, низким порогом входа и прозрачностью. Нужна простая параллельность — запускайте процессы и синхронизуйте их если надо, хоть очередями хоть другими инструментами. Нужна гибкая паралельность — не натягивайте сову на глобус, пожалейте птичку, возмите тот инструмент что вам нужен, хоть scala хоть go, с функционалной записью та же история, PHP не функциональный язык, и им не будет, подход у него не тот. Хотите JS на сервере — ноду вам в руки.

    Странная эта мания превращать один инструмент в другой, потому что привыкли или потому что удобная фишечка. Комбинируйте инструменты а не затачивайте молоток что-бы получить отвертку.

    «В PHP может быть множество задач, которые хотелось бы сделать асинхронно, не дожидаясь окончания выполнения. На ум сразу же приходят работа с большими БД запросами и HTTP запросами. Чтобы составить большой отчет, приходится либо долго ждать, либо пользоваться сторонними решениями, типа очередей. В моем случае, в проекте в большом количестве используются Slack уведомления и Mailgun оповещения. За один клиентский запрос может быть отправлено около десятка HTTP запросов. Почему бы не запустить это все на фоне, а клиенту уже отдать страничку? » потому что «Этот язык был создан для конкретной цели и решает он свою задачу хорошо. Схема „принял — обработал — отдал — умер“ очень эффективна и решает проблему небольших утечек памяти.». Не только кстати утечек памяти.


    1. VolCh
      03.05.2018 13:23

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

      Ничего странного. «Привыкли» ещё ладно, но «удобная фишечка» по сути основной стимул что-то менять.


  1. xobotyi
    03.05.2018 13:10

    Меня в PHP до состояния «аштрисёт» доводят только три вещи (по убыванию бесячести):

    1. Доступ к элементам объектов через ->, которое ну очень часто получается как _> ну или -. (рукопопы как я, которые имеют рассинхрон между руками, поймут). Вот что угодно лучше служебного оператора из двух символов, один из которых по шифту вводится..
    2. Инициализация значений именованного массива через => (ну какого черта не : ?)
    3. Ну и как уже сказал автор — нельзя использовать выражения везде. Да даже если бы можно было хотя бы в строках делать было бы уже хорошо:
      $a = "Hello ${$b?:'hell'}";
      вместо
      $a = "Hello " . ($b?:'hell') . "!";


    1. oxidmod
      03.05.2018 13:23

      По поводу второго — автодополнение от IDE очень даже помогает
      По поводу третьего

      $a = sprintf('Hello %s!', $b?:'hell')


      1. xobotyi
        03.05.2018 13:29

        Оверхед по написанному не находите? =)
        Все что я описал — банальная экономия на символах, с сохранением функциональности.

        Правда, по поводу автодополнения на инициализации массива — не понял… PHPStorm вроде не позволяет такого.


        1. oxidmod
          03.05.2018 13:48

          Вы правы, я имел ввиду первый пункт (->)
          Бес попутал.

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


    1. rjhdby
      03.05.2018 15:36

      По третьему пункту.


      $a='a';
      $b='b';
      echo "Hi $a! I`m $b";

      Раскладывается на такие токены


         1:                     T_OPEN_TAG = <?php
      
         2:                     T_VARIABLE = $a                  
         2:                                  =                   
         2:     T_CONSTANT_ENCAPSED_STRING = "a"                 
         2:                                  ;                   
         2:                   T_WHITESPACE = 
      
         3:                     T_VARIABLE = $b                  
         3:                                  =                   
         3:     T_CONSTANT_ENCAPSED_STRING = "b"                 
         3:                                  ;                   
         3:                   T_WHITESPACE = 
      
         4:                         T_ECHO = echo                
         4:                   T_WHITESPACE =                     
         4:                                  "                   
         4:      T_ENCAPSED_AND_WHITESPACE = Hi                  
         4:                     T_VARIABLE = $a                  
         4:      T_ENCAPSED_AND_WHITESPACE = ! I`m               
         4:                     T_VARIABLE = $b                  
         4:      T_ENCAPSED_AND_WHITESPACE = .                   
         4:                                  "                   
         4:                                  ; 
      

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


      опкод
      opcode                       op1       op2              result
      ZEND_ASSIGN                   $a       'a'                  x4
      ZEND_ASSIGN                   $b       'b'                  x4
      ZEND_ROPE_INIT                       'Hi '    $_tmp_4294967290
      ZEND_ROPE_ADD   $_tmp_4294967290        $a    $_tmp_4294967290
      ZEND_ROPE_ADD   $_tmp_4294967290   '!I'm '    $_tmp_4294967290
      ZEND_ROPE_END   $_tmp_4294967290        $b    $_tmp_4294967290
      ZEND_ECHO       $_tmp_4294967290
      ZEND_RETURN                    1


  1. caballero
    03.05.2018 14:23
    +1

    Лично мне не хватает нормальных аннотаций. Но следует учитывать что все подобные вышеперечисленным вещи усложняют грамматику языка и даже могут сделать ее неоднозначной (потому и не убирается function). Усложнение грамматики — усложнение компилятора. А значит сложнее становится генерация оптимизированого кода. Но в подавляющем числе проектов на PHP никаких особых наворотов не нужно. Гораздо важнее простота, скорость и надежность.


  1. achekalin
    03.05.2018 14:24

    Хочется сказать классическое: «легким движением руки брюки превращаются… превращаются...»

    image

    Впрочем, как из MySQL 3.x вырос MySQL 8.x, так и из PHP постепенно вырастет…

    Но — я бы язык тогда переименовал, а то выражение «умеешь ли писать на PHP» с годами будет означать очередную, новую итерацию языка, во многом отличную от старых — это создаст путаницу. А если подумать (а как без этого?) о совместимости со старым кодом, которого, все же, вагон и маленькая тележка (скажем прямо — из-за него про PHP и помнят), то нужен либо режим совместимости (в php.ini писать «mode=5.5», не к обеду будет PHP5.5 помянут), либо, и правда, язык назвать чем-то вроде NewPHP.


    1. sumanai
      03.05.2018 14:32
      +1

      Зачем? PHP до версии 3 отличается от 4, 5 отличается от 7, и ничего, никаких новых названий не нужно, кроме факапа с 6 версией.


      1. achekalin
        03.05.2018 14:36

        кроме факапа с 6 версией

        Ну вы же сами себе и противоречите. Впрочем, раз в 3 мажорные версии можно и потерпеть пару лет, как скажете. Шутка, лично мне это неприятно.
        Другое дело, что в "новом", расширенном языке что делать — тянуть различия с третьей ветки (я про совместимость), или так и жить в режиме "у вас какая версия того, что вы называете PHP?" Минимум сбивает.


        1. sumanai
          03.05.2018 15:15

          Ну вы же сами себе и противоречите.

          Так название языка всё то же, просто версия, на которую возложили слишком много, получалась настолько плохой, что от неё решили отказаться заранее.
          или так и жить в режиме «у вас какая версия того, что вы называете PHP?»

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


  1. FSA
    03.05.2018 17:57

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

    А это не оно?
    declare(strict_types=1);
    

    Не знаю точно версию языка, где это появилось, но точно после 7.0


    1. sumanai
      03.05.2018 18:36
      +1

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


      1. symbix
        05.05.2018 00:22

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


  1. nezdhanov
    04.05.2018 09:36

    Статья в принципе дает неплохую почву для собственных внутренних рассуждений по вечерам перед сном. Но хотел бы отдельно высказать свое мнение по поводу 9 пункта: на мой взгляд есть вещи исторические, те, которые придают языку свою элегантность, отличают его от других языков, делают неповторимым. Именно такие вещи на мой взгляд, как function, знак доллара перед переменной (или даже два знака доллара), его строки с двойными кавычками, и heredoc'и в которых может происходить мистика на первый взгляд неосвещенного человека, все это и многое другое и делает его именно тем языком, который мы знаем. И исчезновение подобных конструкций, зарезервированных слов и т. д. может смешать языки в одну массу, где в конце концов возможно будет выделяться один Brainfuck и то мало вероятно.