Pull to refresh

Comments 251

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

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


Но давайте вспомним почему в 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 и совместимостью. Но нет, всем надо просто и из коробки.

Я не php-ник, но как-то обдумав преписывание своей CMS (пример сайта), написанной на C++, и отвечая на вопрос автора: «Что Вы хотели бы увидеть или изменить в PHP?», скажу так:
1. Перегрузка функций и методов в естественном виде.
2. Сложные ключи ассоциативных (хеш) массивов.
3. Наследование и полиморфизм, как в C++.
Отсутствие этого (или простая реализация этих пунктов) останавливает меня в использовании php.
Перегрузка функций и методов в естественном виде.

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

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

Сложные ключи ассоциативных (хеш) массивов.

Это просто структура данных. Если вам такое нужно, то реализуйте, делается минут за 5-10.

Наследование и полиморфизм, как в C++.

Это какой? Множественное наследование и возможность «дружить» классы? Это даже не смешно. Или о чём вообще речь?
1. Вот! Использую в C++ постоянно…

2. Про сложные ключи вида (C++, из другого проекта, не CMS):
struct sOptJournalKey
{
int JournalId;
int Id;
_IP UserIp;
bool operator == (const sOptJournalKey &That) const
{
return JournalId == That.JournalId && Id == That.Id && UserIp == That.UserIp;
}
};
struct sOptJournalData
{
//…
};
CMaaUnivHash<sOptJournalKey, sOptJournalData> gOptJournals;

— не хотелось бы придумывать какую-либо склейку полей структуры ключа перед обращением $MyHash[$MyKey] = ..., возможно подойдёт ответ про SplObjectStorage из следующего ответа, php.net/manual/en/class.splobjectstorage.php, но в комментарии 37 говорится, что возможно проблемы.

3. Множественное наследование и виртуальные функции в C++ очень удобны для использования.
2. Читайте про ArrayAccess и аналогичные интерфейсы. Я же сказал, это всё делается элементарно:
class PrefixedArray implements \ArrayAccess
{
    private $prefix = '...';
    private $data = [];
    // ...
    public funciton offsetSet(string $key, $value): void 
    {
        $this->data[$this->prefix . $key] = $value;
    }
}

3. Множественное наследование не нужно. Нет ни одного варианта кода где бы оно было необходимо или хоть как-то оправданно. Это в C++ просто нет трейтов/миксинов и интерфейсов. А виртуальные функции в PHP определяются кейвордом «abstract».

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

Хотя с перегрузкой да, печаль. Но можно вполне реализовывать её на основе рефлексии, что-то вроде:
// oneOf(callable ...$variants): self
// call(...$args): mixed
$dispatcher->oneOf('foo1', 'foo2')->call(23, 42, $arg3);


А там выбирать нужную функцию на основе сигнатуры и предопределённой логики
А виртуальные функции в PHP определяются кейвордом «abstract».

P.S. имеется ввиду те, которые нужно определить в потомке в обязательном порядке. А так любой не финальный метод в PHP является виртуальным.
Перегрузка функций и методов в естественном виде.

с этим есть определенные проблемы:


function foo(string $bar, string $baz);
function foo(int $bar, int $baz);
function foo(string ...$barBaz);

foo('0', '1'); // какую из трех сигнатур должен вызвать php?

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


Сложные ключи ассоциативных (хеш) массивов.

http://php.net/manual/en/class.splobjectstorage.php — и дальше по аналогии. В целом обычно этого достаточно.


Наследование и полиморфизм, как в C++.

  1. наследование классов не очень полезная фича. В этом случае полностью абстрактные виртуальные классы как в вашем любимо C++ — это интерфейсы. И их можете спокойно множественно наследовать.
  2. наследование стэйта — очень простой способ выстрелить себе в ногу.
  3. friend классы не нужны.
  4. Если вы про темплейты (параметризованный полиморфизм) — дженерики появятся рано или поздно, но что-то подсказывает мне что вы не о них. Да конечно это не такая мощная вещь как темплейты но и то хорошо.

Опять же — PHP не претендует на звание хорошего языка. Увы.

Спасибо за ответ.
1. Перегрузку в C++ использую постоянно, в том числе в конструкторах…
2. Возможно, это выход, хотя в комментарии 37 ссылка на bugs.php.net/bug.php?id=49967 (у меня не открывается сайт) о том, что могут быть проблемы. Пример хеш-таблицы на C++ в комментарии выше — CMaaUnivHash<sOptJournalKey, sOptJournalData> gOptJournals;
3. Подразумевалось множественное наследование и применение виртуальных функций, друзей стараюсь не использовать.
Шаблоны — отдельная тема.
Перегрузку в C++ использую постоянно, в том числе в конструкторах…

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


о том, что могут быть проблемы

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


Подразумевалось множественное наследование и применение виртуальных функций

Множественное наследование классов прекрасно заменяется интерфейсами. А потому не вижу проблемы. Что до виртуальных функций — немного непонятно что именно вам нужно. Перегрузка методов в наследниках как бы существует. Абстрактные методы тоже.


В целом ваши притензии больше тянут на "непривычно" нежели "существенные проблемы". Что странно ибо существенных проблем у php много.

UFO just landed and posted this here

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

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

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

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

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

UFO just landed and posted this here
UFO just landed and posted this here

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

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

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

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

Знаю, но не использую, чтобы не создавать привязку к фреймворку.
А каким образом хелперы привязаны к фреймворку? Это примерно как утверждать, что не пользуюсь «sort», а пишу свою сортировку, т.к. «не хочу привязываться к stdlib php». Тот же class_basename выглядит как:
function class_basename($class): string
    {
        $class = is_object($class) ? get_class($class) : $class;

        return basename(str_replace('\\', '/', $class));
    }


Или я чего-то не понимаю?
В текущем проекте эта функция подключается с пути /vendor/laravel/framework/src/Illuminate/Support/helpers.php из состава пакета laravel/framework. Было бы выделено в отдельный пакет, не конфликтующий с этим, да в отдельном неймпейсе — использовал бы скорее всего.
Что вижу в коде, то и говорю. Нет в зависимостях illuminate/support, есть laravel/framework. Не ради этих хелперов, скорее всего, был добавлен фрейм, но увеличивать связанность с ним своими руками не хочется.

Странное, как по мне, решение формально выделить в отдельный компонент часть фреймворка, но не документировать это: laravel.com/docs/5.6/helpers#introduction — где тут о возможности подключить отдельно, без подключения фреймворка? Сравните с аналогичным решением в symfony/symfony — переходишь на страницу документации компонента и первым делом видишь `composer require symfony/`. Возможно, исключительно из-за такого подхода к документированию у Laravel есть образ сильносвязанного фреймворка, где всё друг к другу гвоздями прибито.

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

PS Посмотрел, нет, Eloquent не отдельный компонент, судя по всему, не выделен из illuminate/database. Хотя с новым знаниями глядя на документацию можно было бы так подумать. В документации вообще логика есть? :) Можно разобрать по ней, где отдельный компонент, который можно затянуть в любой проект, а где нужно будет вручную выпиливать?

PPS В любом случае у меня культурный шок, что laravel оказывается не монолит и некоторые из фактических зависимостей от laravel/framework можно одной строчкой в composer.json выделить. Спасибо.
Посмотрел, нет, Eloquent не отдельный компонент, судя по всему, не выделен из illuminate/database.


illuminate/database и есть этот самый Eloquent и миграции.
.А для миграций у нас phinx есть, например.
laravel оказывается не монолит

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

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


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

Array
(
    [0] => 1
    [1] => 4
    [2] => 9
)
Раз такое обсуждение пошло, то внесу и я свои пожелания.

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

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

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

UFO just landed and posted this here
UFO just landed and posted this here
Тут аннотации не то что не помогут, а заставят повторить простыню param просто с другим тегом типа inject. Тут разруха не в клозетах.
Слегка не по теме, но на 2 случай в мадженте есть плагины
Как и все в мадженте, они как бы есть, но использовать можно только где-то в 20% случаях.
Добавить метод через плагин? Нельзя.
Сделать замену метода где используются приватные методы? Можно, но бессмысленно (нельзя).

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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


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

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


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


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

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

Вы бы хотя бы предупредили что там зрелище не для слабонервных...

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

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

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

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


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

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

UFO just landed and posted this here

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

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

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


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


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


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

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

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


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


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

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

Вы же понимаете, что это будет совершенно другой тогда ЯП? Смущает даже более формулировка "неявное временное", в 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, однозначно.

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

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


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

Мне кажется, что 2-ой способ будет выполняться быстрее. Могу ошибаться, не знаток внутренностей PHP.
UFO just landed and posted this here
  1. Т.к. это расширение, то мы уже имеем увеличение вермени от получения запроса до начала его обработки, так как его надо загрузить и подготовить. Ну это я чисто придраться.
  2. Для JSON::encode разрешение имен будет идти абсолютно по такому же пути — сперва будет происходить поиск класса JSON в локальном пространстве имен, а потом в глобальном.
1. Нет, загрузка расширения (и его классов) идёт всего 1 раз во время поднятия PHP (или инстансов php-fpm), а не на каждый запрос.
2. На мой взгляд, код \JSON::encode выглядит гораздо гармоничней, чем \json_encode. Но это чисто моё мнение.

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

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

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

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


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


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

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

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


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

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

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

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


array[<string>, <int>], array[<int>, SomeClass[]]
Ну и про порядок с array_map/array_filter etc. и со строковыми функциями конечно тоже наболело

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

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

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

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

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

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

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

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

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


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

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

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

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


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

array_map/array_filter

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


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

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

image

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

Не изменятся.
в ближайшее время

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

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


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

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


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

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

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


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

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

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

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


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

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

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

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


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

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

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


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


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

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

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

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


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


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


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

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


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


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

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


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

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


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

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


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

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


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

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

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

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


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

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


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

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

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

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

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

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

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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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

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

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


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

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


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

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


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

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


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

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


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

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


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

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

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

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

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

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

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

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


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

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


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

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


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

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


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

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

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

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

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

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

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

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

Понимаю.


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

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


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

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


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

Нет, не веду.


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

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


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

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


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

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


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

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

> Необходимость ставить знак доллара перед каждой переменной — объективный недостаток PHP

Это так же его объективное преимущество, упрощающее и ускоряющее трансляци. Иными словами, объективно это компромисс между субъективными «лучше».

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


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


Возможно у вас есть ещё аргументы против трансляции заранее?

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

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


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

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

PS Почитайте, кстати, почему в Kotlin-е сделали объявления типов справа. Как-никак один из самых приятных для работы современных языков.

никогда даже и не слышали о такой штуке, как opcache

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


И да, я не считаю что в этом вопросе мнение большинства весомо.


почему в Kotlin-е сделали объявления типов справа

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


Так что я не понимаю вашей отсылки.

Популярность PHP не в малой части обусловлена его простотой и толерантностью к ошибкам и новичкам (в общем случае).
И да, я не считаю что в этом вопросе мнение большинства весомо.

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

Аргумент про «если надо, то нагуглят». Это как попытки любителей ручной коробки передач доказать, что АКПП отстой. Да, больше контроля, меньше расход (если быть профессионалом), но 1) порог входа сильно выше, 2) требует постоянного внимания и действий. А людям, в своем подавляющем большинстве, хочется просто крутить руль и жать педали «быстрее»/«медленнее», не отвлекаясь на постоянное дерганье какого-то странного рычага.
Вы так говорите, будто бы префиксная нотация это благо какое-то.

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

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


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

мнение можно учитывать только если оно компетентно. Иначе это не мнение даже.


Может, на самом деле, это вам нужно сменить инструмент на тот, который будет вам удобнее?

аргумент в духе "не нравится php — не пиши на нем". Он не конструктивен и бесполезен. Развивать инструменты значит не нужно?


Это как попытки любителей ручной коробки передач доказать, что АКПП отстой.

Некорректное сравнение. Начиная с того что оно не передает "если надо", заканчивая тем что никто ничего не сравнивает.


Вы сами говорите что ручная коробка чуть меньше ест, но это не повод отказываться от АКПП если вас устраивает.


Ну и тут более корректно сравнение "другой АКПП". Так как подключение opcache не требует никаких дополнительных действий. Это как переключить режим коробки.


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

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


Это ведь вы с потолка взяли про "в два раза дольше парсить" и на основе этого строите весь спор.


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

Это ведь вы с потолка взяли про «в два раза дольше парсить» и на основе этого строите весь спор.
Нет, это я цитировал вас.
мнение можно учитывать только если оно компетентно. Иначе это не мнение даже.
И почему вы решили, что ваше мнение более компетентно?
аргумент в духе «не нравится php — не пиши на нем».
Это не аргумент, а предположение. Если существующий инструмент вам не подходит, то вполне имеет смысл поискать более подходящий. В этом предположении нет совершенно ничего обвинительного или оскорбительного.
Если бы это было не так — они бы чуть чуть заморочались, так как у них упор именно на читабельности.
Вот нет. В кулуарах прямым текстом рассказывают, что именно простота парсера сыграла решающую роль — остальное подтянулось постфактум приятным бонусом. Также это в некоторых докладах Бреслава проскакивало (на ютубе записи с названиями а-ля «введение в Kotlin»)
Словом, ваша позиция мне ясна, моя видимо вам тоже. Следует закругляться.
ну ок
Трансляция заранее превращает интерпретируемый язык в компилируемый

У меня такое впечатление, что мы говорим о разных вещах. Уже упонянутый opcache разве лишает нас каких-то преимуществ скриптовых языков?

Это только предварительная трансляция того, что можно транслировать в компайл-тайме. Опкоды потом интерпретируются.

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

Не полностью, конечно, но решает, да. Главное, по-моему, даже не в замедлении, а в усложнении транслятора.
То есть доллар перед переменными нужен тем, кто пользуется этими редакторами?

Мне нужно внести какие-то небольшие изменения в код или посмотреть на строку, в которой возникает ошибка. Я подключаюсь по ssh, ввожу nano name.php или vi name.php и читаю код. А вы мне предлагаете IDE ставить. На сервер. Который бы в консоли работал. Мне почему-то сразу хочется послать в известном направлении с такими предложениями.
UFO just landed and posted this here
Почему повлияет (не про высоконагруженные, где opcache и прочие).
Операция компиляции происходит при каждом(!) выполнении скрипта. Эта задержка, какой бы малой она не была, добавится ко времени отклика вообще каждого скрипта. Это как раз тот случай, когда экономия на спичках оправдана.

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

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

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

opcache давно по умолчанию в PHP включается.
Включаться включается, но насколько массово используется?

в ubuntu, docker образах официальных и вроде как в centos нет. Там надо ставить отдельно.

Я про то, что включает его не надо. Если установлен, то и включен по умолчанию.
Ничего себе! Я так глубоко не копал. Спасибо, ошибался.

если мне приходится его устанавливать то включить вообще не проблема.

Как по мне, то установить обычно (при использовании пакетных менеджеров) проще, чем включить.
Парсер в PHP достаточно прямолинеен.

это не делает его простым. Да и "ветвлений" там и сейчас не мало. Да, и уже сегодня opcache является тем самым "дополнительным проходом", который занимается устранением мертвых веток из AST, оптимизирует что может и т.д.

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

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

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

чтобы оправдать их существование.

скажите спасибо что в 2018-ом году вы можете назвать метод list или for. Доллар вам мешает.


Просто учитывайте тот факт что до 2012-ого года php разбирал код очень примитивным образом. Контекстно зависимый лексинг там появился тоже не так давно и не сказать что сильно круто сделан.


Сегодня проблема php — отсутствие возможности определить разницу между


yield $foo => $foo ** 2;
и
yield ($foo => $foo ** 2);

(собственно по этой причине нет коротких функций в php).

Сегодня проблема php — отсутствие возможности определить разницу между


А проблема в чём? Скобки определяют группу, т.е. полноценную продукцию (ну или нетерминированную ноду AST), всё внутри парсится как отдельная структура. Получается, что первый вариант — это тупо кей-валью корутина, а второе — велью от лямбды. А ты забываешь, что там (в PHP т.е.) под капотом полноценный LALR парсер, который разруливает такие штуки «на раз-два».

Мне кажется тут другая проблема. В пыхе сделали очень крутую фичу — это секцию use — явную передачу переменных в замыкание, что позволяет GC не бояться и уничтожать все остальные переменные, которые выходят за пределы скоупа (точнее у которых refcount = 0), оставляя только нужные. А в случае таких коротких лямбд — таких переменных не будет, пыху придётся захватывать весь скоуп и держать в памяти. А там и до адовых мемликов не далеко, JS уже через такое проходил. Разве нет?
под капотом полноценный LALR парсер, который разруливает такие штуки «на раз-два».

как бы и да и нет. Я не могу конкретную переписку найти по поводу ограничений, но суть цирка можно описать вот этим сообщением: https://externals.io/message/88651#88836


JS уже через такое проходил. Разве нет?

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

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

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

Да, действительно что-то выделяет. Но хорошо заметно это только при полном просмотре файлов, на diff, с которіми я обічно и работаю, гораздо хуже заметно.
Мне в js наоборот странно когда возле переменной ничего нет, а набирание постоянных let вообще напрягает.
И вообще, если $ все не замечают и никого не напрягает — значит знак выбран удачно. Конечно, кому-то может и не зайти. Я все жду когда для php появятся свой babel и тогда заживем. И вы сможете не писать $)
А в некоторых не только не обходятся с $, но еще и @# юзают… Для переменных :-)
на счёт $ под точно проблема вылезет в том, что в строке "..." не понятно как искать переменную

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


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

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


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

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

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

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

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


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

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

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

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


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

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

Значок $ перед переменными это очень удобно для того чтобы отличать переменную от функции и это как раз выгодно отличает php от многих других языков
UFO just landed and posted this here
UFO just landed and posted this here
Судя по всему, это был сарказм.

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

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

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

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

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

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


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

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

; Okay, guys, now you can choose your favorite currency
; $variable
; €variable
; ₽peremennaya
developer.loved_currency_symbol = $
Вот ещё вспомнилось: autoload для функций

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


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

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

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

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

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


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


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

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

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

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

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

В принципе, можно используя немножко черной магии сделать как-то так уже сейчас:
$b = Array::asort($a, SORT_REGULAR); // получаем новый массив
$a->asort(SORT_REGULAR); // меняем имеющийся массив

Правда даже хуже чем уродливый код будет отсутствие возможности сделать нормальные подсказки для IDE, или я чего-то не знаю о возможностях докблоков.
Всегда выше переменной можно написать пояснение:
/** @var \Class $item */
$item->get();
Немного не эти подсказки, а те — которые определяются докблоком в классе перед методом и используются для автодополнения. Я не знаю как можно объявить что для обычного вызова будет N аргументов и возврат self/void (по вкусу), а для статического вызова будет N+1 аргументов и возврат нового объекта класса.
Вот так можно:
/**
 * @method static someClass get_by_user_id(int $id) Bla-bla
 * @method static someClass get_first_by_id(int $id) 
 */
abstract class a {
...
И oxidmod — классная фича, запомню, но все равно не работает как я предлагал — она позволяет определить параметры для методов с разным именем, но не для одного метода который может быть вызван и статически и нет.
Короче вот так не работает:
/**
 * @method static void method(DocBlockTestClass $newThis, int $arg1, int $arg2)
 * @method void method(int $arg1, int $arg2)
 */


Ну в принципе и фиг с ним, такое двойное использование одного метода с плавающим количеством аргументов и разным контекстом все равно ересь (пока разработчики языка не объявят обратное).
UFO just landed and posted this here
можно используя немножко черной магии сделать
Торжественно клянусь, что замышляю только шалость! Как я уже упоминал — работает, но уродливо до невозможности.
ужаснуться
class ArrayObj {

    public $lArray = [];

    public function __construct($array) {
            $this->lArray = $array;
    }

    public static function __callStatic($name, $arguments) {
        if ($name === 'asort') {
            $newArray = clone($arguments[0]);
            $newArray->doAsort($arguments[1]);

            return $newArray;
        }
    }

    public function __call($name, $arguments) {
        if ($name === 'asort') {
            $this->doAsort($arguments[0]);

            return;
        }
    }

    private function doAsort($type = SORT_REGULAR) {
        \arsort($this->lArray, $type);
    }
}

$a1 = new ArrayObj(["d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple"]);
var_dump($a1->lArray); // ["d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple"]
$a1->asort(SORT_REGULAR);
var_dump($a1->lArray); // ["a" => "orange", "b" => "banana", "c" => "apple", "d" => "lemon"]


$a2 = new ArrayObj(["d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple"]);
$a3 = ArrayObj::asort($a2, SORT_REGULAR);
var_dump($a2->lArray); // ["d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple"]
var_dump($a3->lArray); // ["a" => "orange", "b" => "banana", "c" => "apple", "d" => "lemon"]

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

Fatal error: Cannot redeclare Test::method()
__callStatic и(или) __call
UFO just landed and posted this here
Внутренняя несогласованность в PHP вызвана тем, что язык долгое время развивался людьми, который не имели четкого представления о дизайне языка, а зачастую вообще не понимали, что они делают. Автор статьи продолжает эту традицию.

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

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

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

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

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

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 */"), ' '));
}

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

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

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


use function \{strlen, strpos, array_map, array_reduce};
Дело же часто не в количестве зависимостей как таковых. Очень многими чистые функции стандартной библиотеки и популярных расширений вообще как зависимости не рассматриваются.
Чуть выше написал. Дабы не плодить одинаковых веток.
Такими темпами «наведение порядка» растянется лет на десять. И что конкретно вы подразумеваете под «моделью выполнения»?
Ну на каждый минорный релиз можно.

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

Чем эта модель исполнения принципиально лучше других? Как я понимаю, вы считаете преимуществом то, что под каждый запрос стартует отдельный процесс, который убивается после его обработки?
Новый процесс не стартует на самом деле обычно, но для пользовательского кода это так выглядит. Есть похожая по удобству (в случае интерпретируемых языков) модель CGI, но она заметно медленнее, как раз потому что новый процесс.
Так практически в любом MVC-фреймворке такой же подход: для пользователя важно только то, что на каждый запрос к серверу будет создан класс-контроллер и вызван метод-действие. Более того, можно легко сделать статический кеш объектов (если очень нужно и понимаешь, что делаешь). Не вижу тут преимущества PHP.
UFO just landed and posted this here
Для меня это скорее недостаток, и он очень в духе 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 ничего не было, а данные пропали.
UFO just landed and posted this here
пенять на язык тут не нужно
Ничего подобного. Была проверка на ошибку, но в данной ситуации не было ни ошибки, ни результата. Такую ситуацию я не предусмотрел, и моя претензия именно к принципиальной возможности ее возникновения.

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

Люди ошибаются. Поэтому строители носят каски, а альпинисты используют страховку. И только бесстрашные программисты продолжают писать на языках с неявными эффектами :)
UFO just landed and posted this here
Любопытно. У меня на сервере даже с error_reporting(E_ALL) полная тишина. Правда, я использую IIS — возможно, дело в этом.

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


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

UFO just landed and posted this here
В итоге мы сошлись во мнении, что для написания надежного кода на PHP необходимо все обмазывать параноидальными проверками. Странно, что выводы из этого мы делаем абсолютно разные.
UFO just landed and posted this here
Как это решает проблему возможной опечатки в константе?
UFO just landed and posted this here
Все остальные языки кидают ошибку при обращении к неизвестной переменной \ константе.

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

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

Ruby:
a = B // uninitialized constant B
UFO just landed and posted this here
В моих примерах заведомо некорректная программа останавливается с ошибкой, а в вашем — продолжает работать дальше. Это очень плохо.
UFO just landed and posted this here
А если мне не по нраву стрельба из пушки по воробьям?
UFO just landed and posted this here
Просто попробуйте несколько других языков и сравните, где надежный код получается проще и лаконичнее.
UFO just landed and posted this here

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


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

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

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

Можно по-быстрому набросать преобразование вызова статического метода в вызов стандартной функции, вроде этого:
github.com/uavn/artwrap/blob/master/Art/Wrapper/Hash.php
PHP может стать еще лучше если из него сделать JS? как то так я увидел в статье, с примесью java и scala. Спасибо, не надо ассинхроности, и магии по минимуму. PHP хорош как раз своей относительной простотой, низким порогом входа и прозрачностью. Нужна простая параллельность — запускайте процессы и синхронизуйте их если надо, хоть очередями хоть другими инструментами. Нужна гибкая паралельность — не натягивайте сову на глобус, пожалейте птичку, возмите тот инструмент что вам нужен, хоть scala хоть go, с функционалной записью та же история, PHP не функциональный язык, и им не будет, подход у него не тот. Хотите JS на сервере — ноду вам в руки.

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

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

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

Правда, по поводу автодополнения на инициализации массива — не понял… PHPStorm вроде не позволяет такого.
UFO just landed and posted this here

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


$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. Определение конца выражения — просто взять следующую закрывающуюся фигурную скобку не получится.
  2. Сделать по выделенному куску дополнительный проход токенизатором, так как по сути это инъекция куска кода.
  3. Как-то на этапе компиляции разрулить ситуацию, что перед ZEND_ROPE_* необходимо это выражение вычислить.
  4. Не забыть, что вы можете встроить несколько выражений, да еще и с побочными эффектами.
  5. наверное что-то еще.
Лично мне не хватает нормальных аннотаций. Но следует учитывать что все подобные вышеперечисленным вещи усложняют грамматику языка и даже могут сделать ее неоднозначной (потому и не убирается function). Усложнение грамматики — усложнение компилятора. А значит сложнее становится генерация оптимизированого кода. Но в подавляющем числе проектов на PHP никаких особых наворотов не нужно. Гораздо важнее простота, скорость и надежность.
Хочется сказать классическое: «легким движением руки брюки превращаются… превращаются...»

image

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

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

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

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

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

Не знаю точно версию языка, где это появилось, но точно после 7.0
UFO just landed and posted this here

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

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

В HHVM многое из этого уже сделано.

Да, жаль только что пути HHVM и php разошлись.

Sign up to leave a comment.

Articles