Comments 19

Когда она остыла до комнатой температуры, ее состояние "Ожидает нагревания".

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

Шел 2019 год, программисты PHP продолжали неравный бой с глобальным состоянием...

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

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

В общем, это уже лопата, но ещё не трактор. Лопату можно доверить и зелёному подростку, а вот трактор — нет.
И сколько там солдатов из стройбатов заменяют экскаватор?
PHP практически полностью избавляет программиста от забот параллельного исполнения кода. Поэтому PHP-программисты особо не парясь используют глобальные переменные.

Извините, не вижу связи. Любой MVC фреймворк из 2010 года избавляет программиста от забот параллельного исполнения кода. В том числе и PHP фреймворки. И ни один из них не заставляет (и даже не предлагает) использовать глобальные переменные.


А за 10 лет можно было уже впитать в экосистему хорошие практики, "выкинуть" статьи и книжки, описывающие проблемные места — вернее написать новые, которые заместят старые.


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

В том числе и PHP фреймворки

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


Поэтому ваша отсылка — "в том числе и в PHP фрейморках" — некорректна: от PHP фрейморков в этом плане ничего не зависит, это свойство самого PHP.

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

class Example extends Thread {
    public $value = 0;

    public function run()
    {
        for ($i = 0; $i < 50; ++$i) {
            $this->value += 1;
        }
    }
};

$example = new Example();
$example->start();

for ($i = 0; $i < 50; ++$i) {
    $example->value += 1;
}

$example->join();

var_dump($example->value); // Выводит числа от 50 до 100, когда как
PHP практически полностью избавляет программиста от забот параллельного исполнения кода. | Никакой другой язык этого бы не простил. | Я имею в виду параллельные web-requests, которые приходят на сервер. | PHP защита от переживаний о глобальном состоянии — это на уровне языка.
Неправда. Описанная технология не имеет ни малейшего отношения к PHP, и в действительности является заслугой протоколов CGI и FastCGI, которые реализуют веб-серверы, такие как Apache и nginx. Более того, через эти самые протоколы спокойно подключаются десятки других языков, от питона, руби и луа до плюсов, сей и джавы, на тех же самых условиях — параллельная однопоточная обработка веб-запросов.

Причем фактического ограничения на однопоточность при обработке запроса нет даже в самом PHP, как можно увидеть в примере что приведен глубже в ветке. Это просто не очень целесообразно, но если очень захочется никто не запретит, достаточно включить стандартное расширение pthreads в php.ini.
UFO landed and left these words here
так что это по сути одна экосистема со своими стандартами, язык с веб-сервером взаимно влияли друг на друга
Где я могу об этом почитать? Гугл сходу ничего похожего не выдает, а в статьях посвященных истории разработки PHP Apache упоминается вскользь полтора раза, и то не всегда, и наоборот.
Можете считать PHP универсальным языком без привязки к каким-либо практикам
Такого утверждения я не делал.
многое на уровне языка заточено именно под среду Apach
Что конкретно на уровне именно языка заточено под Apache? Приведите пожалуйста хотя бы один пример.

Основное отличие PHP в режиме командной строки и в режиме веб-программы это переданный набор суперглобалов с инфой о сервере, запросе и т.д. Все его библиотечные функции и биндинги либо есть в стандартных библиотеках других языков, либо несложно подключаются. Все его statements, операторы, типы, и прочие концепции присутствуют в других языках, кроме разве что фич шаблонизатора, но к Apache это не имеет никакого отношения. Связь с веб-сервером при юзе CGI работает через stdin+stdout, т.е. не требует никаких изменений в языке.

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

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

Да и вообще, весьма странно брать «отсутствие в PHP забот параллельного исполнения» как что-то положительное, для чего PHP якобы специально дорабатывался, а позже аргументировать это тем что «в PHP адски хреновая библиотека потоков». Складывается впечатление что эту библиотеку специально хреновой сделали, и за счет этого PHP избавляет от забот о мультипоточности.
UFO landed and left these words here
Но самое классическое применение, которое поощряли даже разработчики самого PHP — это mod_php в Apache
Да, но и этот способ не требует изменений внутри языка или его реализации. Как и у прочих интерпретируемых языков, интерпретатор php может быть легко встроен в другое приложение, что с ним и сделали.
Как минимум стандартные функции, которые начинаются с apache_..., и прочие отсылки к вебу на уровне ядра. Они не выделены в отдельные расширения/модули и валяются в стандартной сборке PHP.
Все эти функции находятся в server-specific расширении apache, которое добавляет тот самый mod_php. Они не являются ни частью языка, ни даже его стандартной библиотеки. Более того, если использовать модули Apache для других языков, они предоставят доступ к аналогичным функциям.
что замысел был в языке для веба
Я с этим и не спорю. Разработчики PHP несомненно учитывали его нишу при выборе направления развития. Моя мысль в том, что никакого конкретного функционала PHP, который бы «избавлял от проблем многопоточности» или «способствовал параллельным web-requests», как утверждал автор корневого комментария, на уровне языка у PHP нет. И уж тем более в нем нет ничего что позволяет утверждать что «никакой другой язык этого бы не простил». Вместо php можно подключить любой другой скриптовый язык без встроенных потоков (или запретить их вручную), например Lua, и в отношении потоков, web-requests и вреда глобальных переменных, все будет точно так-же. Прям один в один.
UFO landed and left these words here
Автор, скорее всего, имел в виду не заточку самого интерпретатора, а то, как его обычно внедряют и используют: в самых популярных связках (Apache + mod_php & nginx + php-fpm)
Автор несколько раз повторил «на уровне языка», «свойство самого PHP» и сделал вполне конкретное утверждение про переменные. По моему смысл вполне однозначен. Жаль только, что в ответ на пример кода и контр-аргументы вместо диалога с пояснением автора, почему я не прав, мне почти сразу же прилетели только минусы и плевок в карму.

Глобальное изменяемое состояние уровня приложения — безусловное зло. Но тут есть еще один момент, которого нет в статье. Есть несколько кейсов, когда глобальное состояние есть и с этим ничего не сделать:


  1. СУБД. Ладно, когда ваше приложение снаружи, вы хотя бы можете сделать вид, что это не ваше дело (на самом деле — нет). Но в финансах много legacy приложений, где основной код написан на PL/SQL или T-SQL. И вот это уже ад в аду.
  2. Когда вы пишете ОС или работаете с железом.
  3. Когда вы пишете своё (нагруженное) сложное приложение (ту же СУБД или что-то подобное)
  4. Когда вы пишете что-то общее уровня приложения. Например кэш (к упомянутой уже СУБД)
    Все эти случаи имеют много глобальных хранилищ состояний той или иной степени модульности и управляемости. Это сильно усложняет и разработку, и тестирование.
Only those users with full accounts are able to leave comments. Log in, please.