Pull to refresh

Comments 94

Насколько увеличивается скорость выполнения пхп-скрипта ???
Есть ли сравнения по времени загрузки среды окружения ??
На RC3 пока не видел бенчмарков, а в целом примерно так.
Сегодня тестировал на винде этот скрипт между 5.6 и 7rc3
www.php-benchmark-script.com
7 RC3 сильно проигрывает в нем по тесту test_stringmanipulation. Под линухом не пробовал.
Смотря какого PHP-скрипта. В целом на реальных приложениях ожидается 30%-50% прирост производительности. Далее все зависит от того что вы делаете в приложении. Огромный профит будет там где идет большой объем работы со структурами данных.
Самый лучший вариант самому написать и по выполнять тесты.
Начиная от версии 4.3.0 до 7.0.0rc3 и hhvm
3v4l.org/3sQhg
Так и вижу анонс: «готовится к релизу PHP12, только теперь он будет называться С#»
Вы так говорите как будто бы это что-то плохое. В целом я был бы рад увидеть в PHP8 JIT, в PHP9 async/await ну и т.д.
ИМХО: не ляжет async/await в PHP, лучше уж нормальные thread-ы с synchronized/volatile и методы wait
вы сами себе противоречите, значит async/await на пых не лягут а треды ложатся, при том что это весьма универсальный механизм управления потоком исполнения, с тредами или просто асинхронным I/O — не суть. Если что, async/await уже реализовано в Hack и уже идет обуждение будущего этого добра в PHP.
Я не против многопоточности в пыхе, я просто против её реализации через async/await. А так это всё пока не очень-то актуально, вот когда я смогу запускать пыху, а не наблюдать как она запускается, отрабатывает и умирает, вот тогда уже можно будет нормально подискутировать о многопоточности, иначе оно просто не имеет смысла.
вот когда я смогу запускать пыху, а не наблюдать как она запускается, отрабатывает и умирает

php-pm, и да, в этом плане больше подходит не многопоточность а event-loop и несколько процессов-воркеров. Многопоточность более актуальна для CLI скриптов.

Штука конечно замечательная, но пых просто сожрёт всю память и на этом всё закончится (слишком много утечек в ядре, т.к. не рассчитан пых на такую работу)
UFO just landed and posted this here
Когда последний раз проверяли php-демоны на утечки памяти? На какой версии?
слишком много утечек в ядре

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

Да и решения в духе php-pm не требуют «переписывания», если у них есть слой абстракций над SAPI (PSR-7, HttpKernel). Эта штука позволяет просто в короткие сроки ускорить приложение за счет невилирования расходов на бутстрапинг приложения. Вы можете после каждой 1000-чи запросов например перезапускать воркеры для надежности.
Ещё не мало интересно что там со скоупами сервисов делать…
А что именно вы хотите с ними делать? Пусть себе висят в памяти, если они состояние не сохраняют. Скажем у доктрины можно просто отчистить unit-of-work и дальше себе пусть висит.
Да пусть висят, просто интересно поведение, если я допустим делаю сервис, зависящий от security.token_storage, то будет ли это нормально работать (пересоздавать мой сервис для каждого нового запроса) или нет?

P.S. В спринге это решается указанием области видимости сервиса: запрос, синглтон,…
можно дропать сервисы в скоупе реквеста, это бы было пожалуй правильно.
Не очень-то это правильно на самом деле это — костыль. К тому же из замороженного контейнера не так-то просто выпилить сервис…

P.S. Ковыряюсь в билдере контейнера, там вроде как есть методы {enter,leave}Scope, осталось придумать как входить в скоуп до создания скоупа реквеста.
UFO just landed and posted this here
Не то, мне не нужно пересоздавать сервис на каждый новый подзапрос, мне нужно пересоздавать на каждый новый master запрос. А вот как запилить свой кастомный скоуп я так и не нашёл (может плохо искал?).
Сервисы не должны особо хранить состояние. Просто подключаем request_stack и забираем текущий master request.
Это конечно хорошо, до тех пор пока кто-нибудь не додумается забирать реквест из стека в конструкторе…
UFO just landed and posted this here
Где курить про shared? (Гугл упорно не отвечает)
Беда, зря это они так :(
Например потому, что скоуп это не нечто привязанное к запросу: я мог бы с лёгкостью (относительной) запилить коннект к rabbitmq и затолкать его ЖЦ в отдельный скоуп, чем городить десяток лишних методов для получения «текущего» коннекта (да, пример высосан из пальца, но всё же… в конце концов можно эту идею привернуть например к long poll и сокетам) + в большинстве случаев проще явно указывать зависимость от текущего состояния в явном виде, а в случае полной замены на request_stack придётся дёргать его в каждом из методов сервиса, а не единожды в конструкторе — это немного ломает всю суть инверсии зависимостей.

Естественно все эти рассуждения нужны лишь если всё запускается демоном, в остальном не актуально ровно полностью.
Скоупы ограничивают доступ и только, они не решают полностью проблем с состояниями, а зависеть от состояния это плохо.
И всё же они ограничивают не доступ, а скорее контролируют ЖЦ. Да, не очень хорошо, но скоупы — это как раз решение, а не проблема.
Скорее PHP#. :)

Впрочем, после перетаскивания ООПа из мейнстримовых строго типизированных языков добавление строгой типизации в передачу аргументов выглядит закономерно, хоть и непривычно и даже холиваристо. Интересно, добавится ли в следующей версии declare(strict_operators=1) и ещё что-нибудь в таком духе…

Вообще, если уж мутировать в шарп, то скорее бы лямбды с нормальным синтаксисом родили. Они уже даже в джаве и плюсах есть, а разрабы похапэ всё упираются.
Справедливости ради, сейчас в стадии голосования почти «нормальные лямбды». Холивар внутри интерналс из-за синтаксиса (почему-то автор RFC не хочет использовать вариант, который ввели уже давным давно в Hack).
Оба-на. Где посмотреть обсуждение?
RFC, Рассылка PHP Internals ну и на гитхабе в пулреквесте к RFC.

p.s. О, занятно, async/await хотят сделать зарезирвированным словом уже в php 7.1. Найс. Асинхронный пых не загорами, того и глядишь, как и в случае с корутинами, ноду обгоним.
Ох, и опять проголосовали против…

Лучше б оператор поменяли на ==>, тогда в запросах YaLinqo будет достаточно удалить кавычки вокруг «строковых лямбд», и синтаксис идеально совпадёт. :)

Странно видеть спор вокруг type hints. Автор в RFC явно сказал, что это техническое ограничение, а не проявление нелюбви к типизации. Добавить их в синтаксис большой проблемы не составит, полагаю, но это ж ещё реализовать надо будет в разумные сроки.

В споре вокруг явности и неявности use какую-либо позицию не принял. Хоть что-нибудь сделали бы уже, хоть как-нибудь.
Ох, и опять проголосовали против…

Против проголосовали именно из-за упертости относительно синтаксиса. Сейчас в интерналс вообще ведут дискуссию по этому поводу исходя из того, что есть же еще тайп хинтинг… ну вы поняли. Все сложно как всегда. В любом случае до 7.1 еще довольно много времени, так что может и сделают норм.
Пых-таки ближе к яве и я был бы не прочь, если бы он продолжал шагать в эту сторону, в конце концов иметь яву с поздним статическим связыванием и опциональной динамической типизацией — есть хорошо, настолько же, насколько хорошо иметь пых с вложенными и анонимными классами, областью видимости для классов в пространствах имён, дефолтной реализацией интерфейсов, и чего больше всего сейчас не хватает: объектами в константах… Эх, что-то я совсем размечтался.
Если вам хочется джавы с поздним связыванием, то существует C# с dynamic. Конечно, на шарпе писать код полностью в dynamic не принято, но это вполне работает. :) В последней версии добавили using static, string interpolation и прочее, так что есть и «глобальные функции», и выполнение кода в строчках, как в похапэ.

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

Вот дефолтной реализации методов интерфейсов нет, здесь джава в кои-то веки утёрла нос шарпу. Что забавно, главные пропагандисты простоты ещё дальше отошли от мантры «множественное наследование — зло». :)
Как там Mono поживает?
Без понятия. А что с ним?
А можно ещё как-то запускать С# под никсами?
.NET Core скоро релизнется.

Так что с Mono? Не слышал, чтобы оно работать переставало. :)
Слышал и видел, что оно не очень хорошо работало, да при этом ресурсов жрало больше чем PHP на той же задаче (сравнивали ASP .NET MVC и Symfony2).
Не слышал и не видел. :)

А ресурсов каких больше жрало? Если при небольшой нагрузке сожрало больше памяти — допускаю. Если жрало больше процессорного времени — это уже что-то странное: шарп при прочих равных должен быть быстрее за счёт статической типизации.
Именно памяти, да.
А какой масштаб чисел вообще? В метрах, в частоте запросов, в процессорном времени?
Ну с учетом того что .NET MVC теперь будут официально супортить под mono и того что мелкомягкие потиху открывают исходники, можно ожидать что через пару лет моно будет вполне себе годной штукой. Вообще жалко что этого не произошло много раньше, как по мне шарп приятнее джавы.
Примерно так, да, через пару лет можно будет об использовании моно в серьёзном (под)проекте с нуля.
Да ладно, многие умудряются делать это уже сейчас. Если верить W3Techs, то ASP.NET имеет 16.5% веба при 12.9% IIS (топ 10 миллионов сайтов по Алексе). Сам удивляюсь. :))
Вы еще вспомните Xamarin, все жалуются но работает.
Что далеко ходить — все на PHP, Java и C++ жалуются, весь мейнстрим завален жалобами по уши. :)
На то он мэйнстрим, не жалуются только на то чем не пользуются.
По-разному. В случае шарпа жалобы на язык слышно редко (ну… от страстных плюсовиков разве что), а вот жалоб на экосистему — хоть попой кушай. На питон жалобы очень редко слышу, хотя, может, я просто слишком далёк от него. При этом людей, считающих синтаксис Obj-C нормальным очень редко вижу.

Ещё у поклонников разных языков разная психологическая устойчивость. Эффект от комментария «PHP говно», «Java говно» и «C# говно» в топиках про PHP, Java и C#, соответственно, будет разным в пересчёте на минусы и карму. :)

Вот, кстати, PHP7 добавил похапэшникам уверенности. Обычно при написании сообщений «на грани», как у меня в этом топике, я без минусов не уходил. А тут — чистота. Первый признак, что язык развивается в нужном направлении, и у похапэшников пропадают сомнения в своём выборе. ;)
Мне просто шарп как вид не очень мил. Моему сердцу родней пачка наблюдателей, а не сигналы/слоты, да и управление многопоточностью я привык оставлять на akka и при необходимости разруливать с тредами, а не лапшой с async/await.

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

Касательно объектов в константах (в пыхе так нельзя, но ОЧЕНЬ хочется):

<?php

class Example
{
    private final static $logger = new Logger(__CLASS__);
    private $someSimpleDependency = new SimpleDependency();

    public function doSomething(Argument $argument = new Argument())
    {
    }
}

class Enum
{
    const SOME_VALUE = new self('some value);
    // ...
}


Это не единственное, чем ява 8 шарпу нос утёрла, ещё монады появились :). Я бы не стал использовать эту фичу в этих целях…
В первый раз вижу человека, который предпочитает ручное разруливание потоков асинк-эвейтам. :)

Моему сердцу родней пачка наблюдателей, а не сигналы/слоты

А какая разница?
Вот такой вот я больной :) Просто если не охота с ними возиться, то и не нужно, есть решения которые это делают сами, а коли уж понадобилось, так пусть у меня будет полный контроль и без лапши в коде.

В механизме управления и «явственности». Ну это опять-таки просто дело вкуса.
без лапши в коде

скажите честно, вы работали с async/await? Ибо пачка наблюдателей проще приведет к лапше.
Приходилось тыкать в go и шарпе. И таки да, как по мне, эта фича больше способствует лапшекоду, нежели набор вменяемых классов (естественно при создании анонимных будет сильно хуже, чем с async/await) наблюдателей.
Одна беда, generics пока нет. Без них выразительность всего этого весьма ограничена.

Я не представляю как бы я писал на TypeScript без генериков.
Вы точно про дженерики? Они то будут может в php 7,1 а вот применимость их к массивам — вот это было бы славно. В TS с этим проще.
Да-да, про них.

Ну, int[], string[] и MyClass[] это вообще само собой разумеющиеся вещи, я сейчас даже не задумался о том, что в опсианной в статье реализации их может не быть.

Более кошерные объявления массивов через женерики тоже приветствуются.

А в TS вообще очень классно систему описания типов сделали. То как там можно описать любой потенциальный Hash с полями, которые в нем точно должны быть, могут быть, могут быть но немного не так…
loadUser() всегда возвращает объект типа User, а findPostsForUser() всегда возвращает integer, нет никакой возможности сделать этот код верным.

Не возвращает, а принимает

function findPostsForUser(int $uid): array {
// Obviously something more robust.
return [new Post(), new Post()];
}
UFO just landed and posted this here
Если программа валится от неправильного типа в параметре или return при теоретической возможности неявного привидения, то это уже не hinting, а строгая типизация (на уровне сигнатур). Но её наличие не должно приводить к увеличению производительности, оно лишь может быть использовано транслятором для оптимизации. Может, но не должно. Основное назначение строгой типизации — это не увеличение производительности, а исключение ошибок неявного преобразования типов.
type-hinting будет работать и без declare(strict_types=1);, под которым я и подразумеваю термин «режим строгой типизации»
UFO just landed and posted this here
Эмуляция строгой типизации в языке на уровне приложения.
UFO just landed and posted this here
А что мешает при этом ему быть строго типизированным?

Вы вообще отличаете строгость системы типов языка от времени присваивания типа переменной? Строгость — это именно контроль типов на уровне языка, недопущение использования одного типа там, где ожидается другой. А получен тип в компайл или рантайме — дело десятое, к строгости оно никакого отношения не имеет
ну так в том то и суть — контроля нет, это именно тайп хинтинг и не более. Контроль только на уровне аргументов и результата работы функций и методов.
Хинтинг — это когда варнинги, а когда программа падает — это уже контроль.
UFO just landed and posted this here
Частично строго типизированный. Сейчас эта часть увеличивается. Глядишь когда-нибудь и тип локальных переменных можно будет обновлять, и '0123' + 456 будет вылетать.
Хинтинг — это когда варнинги


in PHP 5, this will be a recoverable fatal error, while PHP 7 will throw a TypeError exception.


То есть по сути это «варнинги». Просто более громкие. Если вы обернули все в try/catch в php7 то никаких падений.
Нет, это не варнинги. Функция или метод не выполнятся, если неправильный тип передаётся.
Мы недавно с колегой обсуждали эту фичу. Изначально я был только за и всячески пытался показать ее полезность. Но в итоге он заставил меня усомниться не только в пользе скалярного, но и type hinting-а вообще.
Все эти проверки производятся в рантайме, а не на этапе компиляции, которого у PHP нет. И без тестов или просто тестового запуска мы не увидим этих ошибок. И получается, что это нафиг не надо.
Единственный плюс — это помощь IDE-шке. Но эта задача намного удобней решается phpDoc-ами.

И хотя я был ярым сторонником type hinting-а, я не смог не согласиться с его доводом. От статичной типизации есть пользя т.к. проект просто не соберется при наличии ошибки. Но php — это не тот случай. Без проверки (или тестов) мы все-равно потащим ошибку в продакшен и там ее словит пользователь. А с тестами эта штука не нужна.

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


1) Вы так или иначе при разработке запускаете запускаете код (тестами или вручную). Тайпхинтинг позволяет вам быстро определить что на вход методов/функций пришло что-то не то (или ушло что-то не то). То есть увеличивает шансы поймать багу еще на этапе девелопмента. Некоторые настолько упарываются что изобретают DbC для этого, используют ассерты и т.д.
2) тайп хинтинг предоставляет статический анализ PHP кода может быть произведен куда более качественно если у анализатора будет вся необходимая информация о типах.
3) тайп хинтинг в weak моде всегда гарантирует нам что на вход придет именно то что мы запросили, это уменьшает количество кода в различных библиотечных функциях и при этом не нужно хэндлить приведение типов руками. Ошибки будут валиться только при потере данных при касте типов.
3) тайп хинтинг предоставляет тому самому рантайму информацию о типах, которую например может использовать opcache для более глубоких оптимизаций. В частности в internals обсуждалось это дело с позиции будущего внедрения JIT, которому для анпакинга и прочих радостей информация о типах весьма полезна.

От статичной типизации есть пользя т.к. проект просто не соберется при наличии ошибки. Но php — это не тот случай.

неудачный прогон статического анализатора — вот тебе и «не собрался». То что в PHP нет компиляции не означает что мы не можем организовать сборку.

А с тестами эта штука не нужна.

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

оно пока еще сыровато

не сырова-то, а набор необходимых штук что бы прочувствовать всю прелесть тайп хинтинга в пыхе не полон. Не хватает дженериков и типизированных массивов.
В дополнение к вышеизложенному: пускай лучше пользователь словит 500 и в логах будет запись о том, что произошло что-то неожиданное для разработчика, чем в результате очень нестрогого неявного преобразования типов, например, утечёт вся база данных.
Типизация здесь не решает, в той же sql-инъекции строка остаётся string несмотря на наличие кавычек. Лучше в коде явно привести параметр к int, чем каждый раз падать из-за неправильно переданного параметра. Последнее время на проектах некоторые части ипишек на .net или java, сил нет бороться с их 500-ми и трейсами, даже есть правило, если апишка не на php, умножаем время разработки в три раза.
Вы в своей функции укажете, что параметр должен быть int и вам не нужно больше ничего приводить — или вызов до вашей функции не дойдёт, или будет приведение. Я же как клиент вашей функции буду выбирать один из минимум трех вариантов: включить неявное приведение при вызове (вернее не включать строгий контроль), явно приводить при вызове, или пускай падает.

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

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

А если где-то критично важен тип, то не надо принимать скаляры, проси их завернуть в обёртки для примитивных типов, создав Acme\Int, Acme\String, тайпхинтя по ним и работая с умными объектами.
Так в том-то и дело, что не должен, вы ему показываете контракт, который он должен соблюдать. Как он будет его соблюдать, и что ему делать когда почему-то не получилось соблюсти — решать ему, а по умолчанию язык будет пытаться привести к указанному вами контракту.

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

А почему такое разделение на скаляры и объекты? Почему тогда вообще не отказаться от тайп хинтинга?
>>А почему такое разделение на скаляры и объекты?
Потому что в вэбе почти всё строки, от того утиная типизация в php так удобна и экономит столько времени, сил и средств. А все эти новые костыли работают очень криво, от неймспейсов я до сих пор офигеваю открыв исходник и увидев шапку из use.
Потому что в вэбе почти всё строки

Угу, строки, которые нужно потом закастить в инты и флоты, обсчитать чего-нибудь, запихнуть в базу…

Есть не только сайтики в вэбе. А нэймспейсы — это лучше чем классы вида My_Super_Class_With_Snake_Case_Class_Names
Так я об этом и пишу, скаляры надо обрабатывать либо заворачивать в объекты вроде Money или Int, потому и разделяю их.

Про неймспейсы — хрен редьки не слаще. new sfRequest было гораздо удобнее use Symfony\Component\HttpFoundation; new Request;
Есть исторически сложившиеся моменты из-за которых нет нормальной возможности их реализовать удобно, чтобы использовать use Acme\*, нет приватных классов из-за чего скоуп загажен служебными классами и неймспейсами.

Я вот решил написать статейку как мы в кучерявые времена делали свое неправильное DDD. Начал переписывать примеры с php4 на php5 и ловлю себя на мысли, что с интерфейсами и неймспейсами кода стало ещё больше писаться.
от неймспейсов я до сих пор офигеваю открыв исходник и увидев шапку из use

Это потому что неймспейсы можно использовать двумя способами: правильно и как принято в PHP. :) Многие библиотеки множат мелкие неймспейсы, а импортировать каждый класс нужно отдельно. В результате импортирование стало несмешной пародией на инклюды, когда без IDE невозможно угадать, где какой класс разместился.

Подробная статья: pornel.net/phpns

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


Зачем?

Вполне работает что-то вроде:

namespace AppBundle\Entity;

use AppBundle\Entity\SfGuard;

$user = new SfGuard\User();
wiki.php.net/rfc/group_use_declarations

// from FooLibrary use Foo, Bar, Baz; // Nope

use FooLibrary{ Foo, Bar, ClassD as Baz };


хотя на счет синтаксиса — вариант с from как-то лучше, но… контекстно-зависимого лексера на момент реализации этого RFC в PHP еще небыло.
Sign up to leave a comment.

Articles