Заметки об архитектуре или Интерпретатор Forth на PHP 5.3

    О чем пойдет речь?


    Мне очень часто приходится проводить собеседования, нанимая на работу PHP-программистов. 2-3 человека в день — это вполне нормально, хотя и на грани выносливости.

    Все кандидаты разные, кто-то просто великолепен, кто-то похуже. Но у тех, кто похуже, всегда одни и те же ошибки.

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

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

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

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

    Что мы будем делать?

    Давайте попробуем сделать интерпретатор Форта на PHP!

    Форт меня всегда манил, как далекая галактика из антиматерии. Стек, слова в словаре, обратная польская нотация… Это только кажется сложным, но на самом деле очень просто, зато здорово «просветляет» и расширяет кругозор.

    Давайте сделаем наше приложение консольным, никаких браузеров и серверов. Давайте писать его на PHP 5.3, стараясь использовать язык на 100%. И, конечно же, попробуем изначально сделать так, чтобы пришедшие после нас не повесились от нашего кода в первый же день.

    Архитектура приложения

    Мы с самого начала договорились с вами, что пишем на PHP 5.3, а это значительно облегчает работу системному архитектору. Примем сразу несколько принципов, которых будем придерживаться в ходе разработки:
    1. Для разделения уровней приложения используем пространства имен
    2. Каждое имя класса должно однозначно указывать на его место в файловой системе
    3. Один класс — один файл
    4. Все классы включаются только через автозагрузку
    5. Все ошибки обрабатываем исключениями, классы исключений подчиняем общим правилам

    Возьмем в качестве корневого пространства имен для нашего приложения \FORTH. Основные классы Форт-машины положим в \FORTH\SYSTEM, а исключения будем располагать в \FORTH\EXCEPTIONS, которое само по себе тоже разделим на несколько, например — \FORTH\EXCEPTIONS\SYSTEM для исключений, возникающих в самой Форт-системе и, скажем, \FORTH\EXCEPTIONS\STACK для исключительных ситуаций, связанных со стеком.

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

    Получается примерно такой код:

    <?php
    
    $autoload = function ($class) {
    
    	$path = explode('\\', $class);
    
    	if ( 'FORTH' != array_shift($path) )
    		throw new \FORTH\EXCEPTIONS\SYSTEM\NamespaceIsWrong();
    
    	$filename = array_pop($path);
    
    	require __DIR__ . '/' .
    		implode('/', array_map('strtolower', $path)) . '/' . 
    		$filename . '.php';
    
    };
    
    spl_autoload_register($autoload);


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

    Берем этот код и кладем его в файл autoload.php в корне проекта.

    Настраиваем запуск

    Перед тем, как писать реальный код Форт-машины, нам нужна точка входа. Ее обеспечат три файла — forth.php будет инициализировать приложение и реализовывать главный цикл, а forth.bat и forth.sh будут играть вспомогательную роль, помогая запустить наш скрипт в режиме командной строки в разных ОС.

    Под Windows файл forth.bat может выглядеть примерно так:
    @echo off
    SET PHP_PATH=Z:/usr/local/bin
    %PHP_PATH%/php -q ./forth.php %1 > output.txt
    type output.txt | more
    pause


    Я уверен, что читатели этого топика с легкостью его улучшат и с удовольствием создадут аналог для запуска нашего приложения под sh/csh/bash или любой другой командный интерпретатор.

    Точку входа приложения, файл forth.php, оставим пока почти пустым, внесем в него лишь две строчки — объявление пространства имен и инициализацию автозагрузки
    namespace FORTH;
    require __DIR__ . '/autoload.php';


    Стек и очередь команд

    Настало время реализовать две главные части нашей Форт-машины: стек и очередь команд.

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

    В PHP стек LIFO отлично реализуется массивами и операциями array_pop и array_push, поэтому не будет изобретать велосипед, а воспользуемся этими средствами. Учтем, что в данной реализации стек у нас может быть только один, поэтому сделаем класс стека синглтоном. У нас получится примерно такой код:

    <?php
    
    namespace FORTH\SYSTEM;
    
    class Stack extends Singleton {
    
    	private $stack = array();
    
    	public function push($obj) {
    
    		array_push(
    			$this->stack,
    			$obj
    		);
    
    	}
    
    	public function pop() {
    
    		if ( $this->isEmpty() )
    			throw new \FORTH\EXCEPTIONS\STACK\StackIsEmpty();
    		
    		return array_pop(
    			$this->stack
    		);
    
    	}
    
    	public function isEmpty() {
    
    		return empty($this->stack);
    
    	}
    
    }


    Позвольте, скажете вы — а где же синглтон? Где же закрытый конструктор, привычный метод getInstance()?

    Все просто — мы вынесли весь фунционал паттерна в специальный системный абстрактный класс \FORTH\SYSTEM\Singleton. Если Вы внимательно посмотрите код этого класса, то поймете основную идею — как LSB, появившееся в PHP 5.3 позволяет разделять абстрактное описание паттерна и его конкретную реализацию.

    Совершенно аналогично с помощью массива организуем очередь, только используя функции array_push и array_shift.

    Словарь

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

    Слово будем представлять в виде объекта класса \FORTH\SYSTEM\Word, а словарь — \FORTH\SYSTEM\Dictionary, реализацию этих классов вы найдете в исходном коде приложения.

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

    Стоит отметить, что класс словаря тоже несомненно должен быть реализован как синглтон, кроме того словарь уже при старте Форт-машины должен содержать в себе некий минимальный стандартный набор слов, так что кроме непосредственно класса \FORTH\SYSTEM\Dictionary нам потребуется реализовать класс StandartDictionary, выполняющий инициализацию словаря стандартными словами, а также добавить инициализацию стандартного словаря в точке входа в приложение.

    Для начала реализуем в качестве стандартных слов четыре основные арифметические операции, «DUP» — удвоение числа на вершине стека, «SWAP» — перестановку двух верхних чисел со стека и "." — вывод числа с вершины стека. Особой сложности это не составит, вот как выглядит пример для сложения двух чисел:

    
    		/*
    		 * Сложение двух верхних чисел, помещение результата на стек
    		 */
    		$dict->addWord(
    			new Word(
    				'+',
    				2,
    				2,
    				function ($a, $b) {
    					return (array)($a+$b);
    				}
    			)
    		);


    Общаемся с внешним миром

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

    Набросаем следующий код в forth.php:
    $data = \file_get_contents($argv[1]);
    
    $parser = SYSTEM\Parser::getInstance();
    $parser->loadRawData($data);
    $dataForQueue = $parser->makeQueue();
    
    $queue = SYSTEM\Queue::getInstance();
    $queue->loadArray($dataForQueue);
    
    $stack = SYSTEM\Stack::getInstance();
    
    $executor = SYSTEM\Executor::getInstance();
    $executor->setStack($stack);
    $executor->execute($queue);


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

    Ничего сложного в коде «парсера» нет, наша задача очень проста — разбить строку по пробельным символам, а далее обработать. Если мы встречаем число, то просто поставить его в очередь, если же некий символьный литерал — спросить словарь, не является ли он словом, и если это действительно так — поставить в очередь объект-слово.

    Гораздо интереснее код «палача». Исполнитель по сути представляет собой ядро Форт-машины — именно он оперирует со стеком и исполняет слова. Мы передадим ему объект нашего системного стека, загрузим в него очередь команд и попросим эту очередь над данным стеком выполнить.

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

    Выглядит это примерно так:

    
    $args = array();
    
    for ( $i = 1; $i <= $word->getStackPopCount(); $i++ )
    	$args[] = $this->stack->pop();
    
    $args = \array_slice($args, 0, $word->getOperandsCount());
    
    $result = \call_user_func_array($word->getCallback(), $args);
    
    if ( !\is_null($result) ) {
    	foreach ( $result as $res ) {
    		$this->stack->push($res);
    	}
    }


    Что получилось?

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

    Для кого-то этот топик, возможно, откроет что-то новое — я буду только рад.
    Кто-то прочтет и скажет «ну это же элементарно, что тут нового» — отлично.

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

    А я пошел спать -))

    Исходный код

    По мере написания этой статьи я выкладывал то, что получалось, в специально созданный проект на Google Code, откуда вы можете взять исходные коды: code.google.com/p/php-forth/source/browse/trunk

    Код лицензирован под GPL v.3

    Список литературы

    1. ru.wikipedia.org/wiki/%D0%A4%D0%BE%D1%80%D1%82_%28%D1%8F%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%29
    2. ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B5%D0%BA
    3. ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D1%81%D0%BA%D0%B0%D1%8F_%D0%BD%D0%BE%D1%82%D0%B0%D1%86%D0%B8%D1%8F
    4. Вдохновлявшая меня советская книга про Форт, фиолетовая такая, для детей старшего школьного возраста, не помню ни название, ни выходные данные...
    Поделиться публикацией

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 234

      –18
      А какой смысл писать что-то не для сайтов на PHP?
        +7
        А почему бы и нет. PHP — скриптовый язык программирования общего назначения ru.wikipedia.org/wiki/PHP
          –4
          Про консольные утилиты, надеюсь, никто не говорит. Поэтому можно предположить нечто из разряда демонов. А не подходит PHP для них, именно потому что предназначен для сайтов. Время жизни исполняемого кода очень низкое. Это оставляет сильный отпечаток на той же работе с памятью.

          ЗЫ:… и это если очередной раз не тыкать палочкой в то, как язык PHP был спроектирован
            +4
            Почему бы и не консольные? Да и демон вполне может быть для сайтов, вроде даже веб-серверы есть чисто на php, как и тру fastcgi. По-моему, с полгода как у php с временем жизни кода и утечками памяти проблем не больше, чем у других языков его класса.

            Если нужна программа в ограниченные сроки, то лучше, имхо, воспользоваться хорошо знакомым языком, чем начинать изучать новый, пускай и теоретически лучше подходящий для этой задачи, тм более если языки из одной весовой категории (я про php/python/ruby/perl). Новые языки надо изучать или just for fun, или если работодатель/заказчик согласен оплачивать вхождение и допускает повышенную вероятность срыва сроков. Рассуждать про себя в стиле «на хабре в комментах пишут, что писать на python/ruby быстрее, чем на php, но я их не знаю толком, потому возьму времени как на php» несколько неэтично, имхо — может прокатит, а может нет. У меня вот с python не прокатило, хорошо хватило времени переписать всё в авральном режиме на php+gtk.
              0
              5.3 со сборщиком мусора всё гораздо лучше чем раньше
                +2
                Время жизни у них бесконечное, если не скапливать в памяти классы и переменные.
                  0
                  у меня был демон-парсер на PHP, работал больше месяц без перерыва. я его завершил только потому, что захотел изменить конфигурацию.
                +14
                Вот представте на минуту что знаете только PHP и вам вдруг понадобилось быстренько написать какую то консольную утилиту, которая скажем файлики перегоняет из одной кодировки в другую.
                Вы скорее всего быстренько набросаете ее на PHP и будете радоваться тому что успеете сделать что то еще.
                • НЛО прилетело и опубликовало эту надпись здесь
                    +14
                    В который раз отпишусь — любой язык это инструмент — плохой или хороший, удобный или неудобный это решать тому человеку кто его использует. Вы просто не умеете его готовить :-D И это — Ваши проблемы.

                    Обезьяне все равно что у нее в руках — линейка или лазерный дальномер — применет она его всегда одинаково :P
                    • НЛО прилетело и опубликовало эту надпись здесь
                        +6
                        В 19 лет это часто случается — хочется многое, если не все, изменить, а уверенность в полном познании чего-либо — непоколебима. Нет, ну серьезно.
                          +1
                          Пардон, 20.
                          • НЛО прилетело и опубликовало эту надпись здесь
                              +1
                              аргументируй. чего ему не хватает чтобы быть СОВРЕМЕННЫМ. думаю, ты расскажешь лишь о фишках, которые даже древнее самого php.

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

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

                              • НЛО прилетело и опубликовало эту надпись здесь
                                  +1
                                  Да просто старайтесь потоньше троллить. А то не интересно даже становится.
                                    +4
                                    то, что ты напишешь в профиле не важно, а вот комменты твои почитав становится понятен типаж.
                                    сплошь вода и отсутствие конкретики, вот и сейчас тупо уход от конкретного вопроса об аргументах. начитался чужих мыслей и мнений в интернетах и вперёд на подвиги достойные ксерокса.
                            +4
                            словосочетание «морально устаревший», применяемое по отношению к языку — это просто смешно.

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

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

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

                            • НЛО прилетело и опубликовало эту надпись здесь
                                +1
                                А как Вы меряете устаревание языка? По каким параметрам?

                                Вы будете удивлены, каждый год создается очередной язык «изначально проектировавшийся чтобы сделать разработку под встроенные системы удобней, чем при использовании C + ASM»

                                Уже создано Over 9000 стандартов, которые парсятся быстрее, удобней для восприятия человеком, занимают меньше места, чем XML.

                                Про SQL и HTML 4 я вообще молчу. Почитайте блог NoSql и пару статей про HTML5
                                • НЛО прилетело и опубликовало эту надпись здесь
                                    +3
                                    Запрос в гугл на фразу «Php устарел» приводит нас на один форум, где идет вялый холивар ниочем.

                                    Так что, к сожалению, Вашу аргументацию без пруфлинка я принять не смогу.
                                      0
                                      > А узнать про «устаревание языка» вы сможете поискав это в гугле

                                      С этого и надо было начинать: что вы считаете это так, потому что «народ так говорит». В вашем возрасте довольно типично принимать на веру мнение нескольких гуру, не особо разбираясь почему они так считают. В противном случае, вы приводили бы аргументы, а не ссылались на «общественное мнение».
                                        –2
                                        Ни один гуру подобную ерунду не напишет.

                                        Гуру изящно решают проблему нужными инструментами, а не забивают гвозди микроскопом, приговаривая что «молоток устарел»
                            +9
                            Чувак, ну ты жжош, ты наверно до сих пор живешь 4-м PHP )))).
                            Давай минусуй карму в отместку. )))).
                            • НЛО прилетело и опубликовало эту надпись здесь
                                +4
                                Реализовано, и реализовано отлично, чуть менее чем полностью как в яве, в яве по-вашему тоже ООП нет? А где тогда есть? :) Вы тогда пишите уж более предметно чего вам не хватает.
                                • НЛО прилетело и опубликовало эту надпись здесь
                                    +5
                                    Аргументируйте.
                                      +1
                                      Реально единственный аргумент — это то, что базовые типы не являются объектами.

                                      Но это без проблем обходится.

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

                                      Но к этому привыкаешь.

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

                                      Да на самом деле, для любого языка можно наскрести таких «недостатков» и таких «но».

                                      А проще всего не ныть. А то придется отрезать то, что танцевать мешает.
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                          +3
                                          Конечно PHP уныверсальный язык

                                          1. Для Web
                                          2. Для скриптов
                                          3. для разработки десктопных приложений habrahabr.ru/blogs/php/19004/

                                          При наличии правильного набора расширений на PHP можно писать практически все.

                                          Другое дело, что его для этих целей не используют, потому что есть промышленные стандарты и более удобные решения для программистов.
                                            +1
                                            Проблема скорее в том что некоторые относятся к PHP с предвзятостью основанной на слухах и мнениях ;)
                                    +5
                                    Да я не смеюсь.

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

                                    Отвечаю сразу же на предполагаемые вопросы:
                                    > Множественного наследования где?
                                    — Есть, через интерфейсы, как в Java и С#

                                    > Проперти где?
                                    — Есть, но честное слово не пользуюсь, и в советах по оптимизации тоже не советуют. (ввиду того что это интерпретируемый язык), лучше пользоватся методами.

                                    > PHP говно, медленно работает
                                    Упс, пишите либы для PHP на чистейшем Си, а можете и на C++

                                    > (задаем математически) PHP говно, потому что это говно, потому что это говно, ..., потому что это говно.
                                    Ничем прокомментировать не могу. Вероятно вы правы.

                                    На другие вопросы тоже попробую ответить.
                                    • НЛО прилетело и опубликовало эту надпись здесь
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                          +1
                                          > Когда человек пишет на php5, он по сути пишет на старом добром php4, попутно заворачивая это всё в некие подобия классов.

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

                                          PHP имеет популярность, как язык на котором можно за 1 день научиться клепать сайты и быдлокодить на фрилансе — и это печально. Однако, в PHP есть и неймспейсы, и мощное ООП, и стандартные интерфейсы для работы с данными посредством итераторов и «как с массивами», и многое другое.
                                          Как ни начнешь смотреть резюме и высказывания php-программистов, так все — прям такие программисты, прям такие спецы. А на деле — говнокодят на уровне PHP4 и функции на 800 строк пишут(не с потолка пример взят будет), и ни-че-го не знают о возможностях актуальной версии языка. Зато, конечно, утверждать, что язык говно могут все — ну тут ума много не нужно; сказать, что и, например, C# говно(я на нем никогда не писал, но пусть — важно же сказать) тоже всякий может:)

                                          В глобальной области видимости, конечно, фигова куча функций, которые пилились всю историю языка и никто никогда не задавался вопросом стандартизации наименования — это выглядит кошмарно. Из-за этого, безусловно, язык кажется страшненьким. Но, право, никто никогда не использует весь этот набор из 9000 функций — а сотню слов запомнить уж как-нибудь можно.
                                            +2
                                            > PHP имеет популярность, как язык на котором можно за 1 день научиться клепать сайты и быдлокодить на фрилансе — и это печально

                                            С другой стороны, это говорит о простоте и хорошей реализации под конкретную задачу, что можно отнести к достоинствам. Никто не начинает с первого дня писать хороший код, нужно время проб и ошибок, в котором будет и быдлокод. Тот кто быдлокодер по сути — будет быдлокодить на любом языке, кто растет со временем — будет писать хороший код и на бейсике
                                    +6
                                    Знаю, например, PHP, C, Asm, основы Java, Erlang и Common Lisp. На чём из них мне писать одноразовую консольную утилиту, к которой основное требование скорость разработки?
                                      0
                                      на shell-scriipt? :)
                                        0
                                        Его в списке нет :) Или нет на целевой/рабочей машине знакомого шелла (command.com на *nix может и не оказаться :D )
                                          +9
                                          Bash язык куда хуже PHP.
                                            –1
                                            Он и не должен быть «лучше». Это же случай DSL, нет?
                                          +2
                                          python :D
                                            –1
                                            Вхождение в python, а главное его библиотеки, и разработка на нём будут быстрее, чем разработка на php? :) Если на утилиту по перекодированию файлов и граббингу сайта дадут год, то может и быстрее. А вот если день?
                                              +2
                                              Ну я как-то на вхождение потратил один день, срочно надо было, код конечно не такой красивый как сейчас был, но работал.
                                              Перекодирование там в codecs, а граббинг в urllib.
                                              Примеров море, но даже без примеров разобраться с help(urllib)
                                              В 3ем питоне это еще проще чем во 2ом.
                                        –1
                                        Лучше воспользоваться iconv из командной строки, чем из командной строки вызывать php передавая ему php код, который вызывает iconv
                                          +1
                                          Если задача чуть посложнее, чем перекодировка одного файла с известным именем в другой файл с известным именем, то «обвязку» для вызова iconv делать придётся по любому. Так ли велика разница делать её средствами sh или php? Особенно, если второй язык знаешь намного лучше, чем первый, а сделать надо вчера.
                                            +2
                                            Ну там может быть нужно не просто конвертировать, а ещё с какой-то заковыкой, которая потребует как минимум знания sh. А человек его не знает. Зато знает php.
                                        +4
                                        Некоторое время назад я познакомился с python, и понял, что я терял все это время.
                                          +2
                                          через некоторое время вы познакомитесь с Java (Modula, Ruby, Scala, C# выбрать, подставить из списка своё) и так же подумаете.
                                            +3
                                            Уверен, что большей языка-помойки, чем php, из более менее современных языков я уже не найду.
                                              –10
                                              Хотя что же я… Есть еще его уродливый брат-близнец — perl…
                                                +12
                                                Все таки области применения у них разные, так что ваше «брат-близнец» как-то не совсем к месту.
                                                Вспомнилась великолепная цитата:

                                                PHP — это маленькое зло, созданное некомпетентными новичками, в то время как Perl — это большое и коварное зло, созданное умелыми, но извращенными профессионалами.
                                                — Jon Ribbens
                                                  0
                                                  Вот про Perl зря вы, если вы не знаете языка, то иногда лучше помолчать, а то ведь холиварить просто, а выложить по существу архитектуры языка будет сложнее.
                                                    0
                                                    Области применения разные? Вы данную статью читали?
                                                      +1
                                                      Ви таки вапгосами изволите-с?
                                                      Читал и что с областями не так? Сделал человек модель языка Forth молодец, в чем проблема и почему у него всё работает, а вам не нравится?
                                                        0
                                                        Что именно про Perl я «зря»? То, что его код выглядит одинаково до и после RSA шифрования?
                                                        У него всего работает, только причем здесь это? Фома и Ерема?
                                                          0
                                                          Вы, видимо еще не освоили языки, после которые у вас возникает отвращение как php, так и к perl.
                                                            0
                                                            У вас горячка, нормально читается код на Perl, RSA шифрование это лишь глупая шутка, если вы не знаете какого-то языка и не умеете на нём читать, то это лишь ваша проблема, он не становится хуже от этого, сотни тысяч других людей умеют и любят читать Perl листинги.

                                                            Я например по китайски не умею читать, но при этом не ругаю его, учу.
                                                              0
                                                              Все верно, в тру языках необходимо предупреждать, что файл закодирован:
                                                              #!/usr/bin/python
                                                              # Did you know Python can use any obscure encoding: rot13, zlib, among others, for the source code?

                                                              cevag h"Uryyb jbeyq!"
                                                        –2
                                                        Что ж вы так. Не зная броду, головой в воду ;)
                                                          +2
                                                          Perl подарил миру такую замечательную вещь как регулярные выражения. Библиотека PCRE ( дословная расшифровка — регулярные выражения как в перле) нынче является неотъемлемым атрибутом любого приложения связанного с web.
                                                          0
                                                          Не зарекайтесь ;-)
                                                          +2
                                                          Не подумает :)
                                                          +1
                                                          Некоторое время назад я познакомился тоже с Python, и понял, что не терял ничего все это время. В итоге я учился программировать а не PHP, это не одно и то же.
                                                          +9
                                                          В автолоадере, чтобы не было конфликтов, надо не эксепшн кидать, а возвращать false, чтобы передать управление следующему автолоудеру.
                                                            –3
                                                            И так до бесконечности… -))
                                                              +3
                                                              Разве количество автолоадеров бесконечно?
                                                            +8
                                                            а зачем, если использовать язык на 100%, реализовывать стек и очередь, когда есть SplStack и SplQueue? ;) Кроме того, синглетоны — плохая практика (привет, глобалс!) и там не нужны
                                                              +6
                                                              Я вот тоже не понял, зачем там Синглтон. Наверное, просто слово модное.
                                                                0
                                                                Вообще незачем, конечно. Исключительно ради одной вещи — показать LSB в действии. Искал наглядный пример.
                                                                  +3
                                                                  Получилось плохо. Совсем не в тему.
                                                                    +6
                                                                    Вообще, синглтон — плохой паттерн. Точнее он не плохой сам по себе, но то, как его суют везде, где он не нужен — просто кошмар.
                                                                      0
                                                                      Соглашусь.
                                                                      Но все-таки, по существу — что крайне плохого в class A extends Singleton {}?
                                                                        +3
                                                                        Плохого, что в данном контексте он совершенно не нужен. А в extends Singleton, по сути, плохого почти ничего. Синглтон так редко нужен, что не имеет смысла создавать отдельный класс, от которого наследовать. Проще каждый раз прям в классе добавлять данные, а единственный родительский класс оставить для чего-то другого. Примесей ведь в php пока нету.
                                                                          0
                                                                          То есть в данном учебном примере «по сути, плохого почти ничего».

                                                                          Ну и отлично.
                                                                            +4
                                                                            Нет, не переворачивайте мои слова и не выдирайте их контекста.

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

                                                                            В записи «class A extends Singleton» вне контекста — ничего плохого нету, но она бывает нужна крайне редко.

                                                                            Но, еще раз повторю, именно в этом контексте такая запись — крайне вредная, потому что она учить людей делать неправильно!
                                                                              –2
                                                                              Я понял, есть два мнения — Ваше и неправильное.
                                                                              Спасибо за разъяснение.
                                                                                +1
                                                                                Я понял, есть два мнения — Ваше и неправильное.
                                                                                  +2
                                                                                  Боюсь это не только его мнение, но и мое.

                                                                                  А конкретно почему плох Queue extends Singleton. Что делать, если в будущем нужны будут две разные очереди?
                                                                                    +1
                                                                                    Убрать extends Singleton.
                                                                                    Добавить abstract class Queue.
                                                                                    Отнаследовать от него Queue1 и Queue2.
                                                                                      +3
                                                                                      Забыли еще кое-что. Убрать Queue::getInstance(), который разбросан по всему коду. И зачем надо было создавать себе всю эту лишнюю работу и ограничиваться в гибкости кода?

                                                                                      Кроме того, наследовать ничего не надо:
                                                                                      $q1 = new Queue();
                                                                                      $q2 = new Queue();
                                                                                        0
                                                                                        Просто затем что мне была нужна только одна очередь.
                                                                                          +2
                                                                                          Из вас плохой архитектор)
                                                                                            0
                                                                                            Ваше мнение для меня ценно, спасибо.
                                                                                              +1
                                                                                              я тоже подпишусь. вы плохой архитектор.
                                                                                                +2
                                                                                                передайте ещё, что и singleton он не умеет правильно готовить, clone не закрыт.
                                                                                                  0
                                                                                                  sleep тоже
                                                                                                  +3
                                                                                                  Хужк всего то, что вы проводите собеседования.
                                                                                    +1
                                                                                    Что отлично то? Хорошего и полезного тоже ничего нет. Для демонстрации LSB есть более удачные примеры. Например, ActiveRecord
                                                                                      +3
                                                                                      Singleton нужно использовать тогда и только тогда, когда стоит ограничение на количество объектов — может существовать только один объект данного класса и большее количество обрушит систему или разрушит логику приложения.
                                                                                      Вы же использовали Singleton потому что была нужна только одна очередь.
                                                                                0
                                                                                Если Вы показываете новый фичи PHP 5.3 на таком примере, то где же __callStatic, __invoke и, конечно же, goto?
                                                                                  0
                                                                                  В 5.3 конечно же -))

                                                                                  Вы еще забыли deprecated ereg*, use, NOWDOC, ?:, array_replace(), preg_filter() и еще кучу всего, что я наизусть не помню.

                                                                                  А, еще asinh() и acosh(). Как же.
                                                                            +4
                                                                            Похоже, 5.3 дает писать на джаве на пхп. Но корней не скроешь: "require __DIR__ . '/' . implode('/', array_map('strtolower', $path)) . '/' . $filename . '.php';" — срыв башки вообще.
                                                                              +1
                                                                              ну этот кусок можно переписать проще ведь:
                                                                              require sprintf('%s/%s/%s.php', __DIR__, strtolower(implode('/', $path)), $filename);
                                                                                0
                                                                                И чем стало проще, кроме того, что Вы искуственно зачем-то ограничили число уровней вложенности?
                                                                                  +1
                                                                                  где?
                                                                                    +1
                                                                                    Сорри, неправ.
                                                                                  +2
                                                                                  Спасибо, прямо полегчало. :) Я, честно, очень давно уже на пхп не писал, но смутно припоминаю всю эту кошмарную идею с автолоадом. Это чтобы имя класса поменять, надо еще и файл переименовать? Эээ, а версии контролировать не надо? Представляю себе version hell, когда появляется обертка какого-нибудь корневого класса. Хотя может я и неправ, и никто так не делает, и это просто чтобы «проиллюстрировать LSB», или как там говорится.
                                                                                    0
                                                                                    а в Java разве не надо переименовывать файлы? В пхп да, обычно имя класса == название файлу, структура папок должна повторять структуру неймспейса. На деле сложно конечно, но в то же время и удобнее
                                                                                      0
                                                                                      А что сложного то?

                                                                                      Мне с моей С# колокольни и навязчивыми предупреждениями от СтайлКопа по другому и не видиться.
                                                                                        +2
                                                                                        Многим видится излишней структура «один файл — один класс», дублирование сущностей. Кажется ненужной роскошью выделять отдельный файл под класс из трёх-пяти строк, пока проект помещается в голове и/или умная IDE помогает перейти к определению класса или вставить отсутствующий include.
                                                                                          +2
                                                                                          Многим видится излишней вообще хоть какая-то структура, но это не значит, что не нужно структурировать код.
                                                                                            +3
                                                                                            Когда структурирование кода приводит к нарушению DRY (а «1 файл = 1 класс» — именно такой случай), встает вопрос сразу о полезности такого структурирования (или об адекватности языковых средств?).

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

                                                                                            Необходимость создавать по файлу для каждого класса — это нарушение как DRY, так и KISS. Почему эта необходимость возникает возникает (из-за неадекватности языковых средств? из-за «архитекторов», которым хочется создавать «архитектуру»?) — это уже другой вопрос. Можно придумать ситуации, когда такой подход будет оправданным, но «по дефолту» — подход кажется неверным.
                                                                                              0
                                                                                              Аргументируйте. В каком месте это нарушение DRY и, тем более, KISS? Вы предлагаете хранить всё в одном файле?
                                                                                              Между прочим, Java иначе и не позволяет орудовать с собой.
                                                                                                0
                                                                                                DRY очевидно — повтор имени неймспейса и класса в пути и имени файла. Если не использовать autoload, то и KISS под вопросом — инклудить, скажем, два файла вместо одного явно не проще.
                                                                                                  +1
                                                                                                  Автолоад использовать, естественно.
                                                                                                  Хорошо, какая альтернатива такому подходу? Хранить всё в одном файле?
                                                                                                    0
                                                                                                    Не умножать сущности сверх необходимого. Фактически для меня в таких ситуациях стоит выбор между DRY и KISS. То ли использовать простую схему отображения неймспейсов и классов на ФС, то ли путём усложнения autoload объединять связанные классы (родитель-наследники или сущность-хранилище, или ещё что-то) в одном файле.
                                                                                                      +2
                                                                                                      Такс. Я таки не могу понять, как хранить иначе, чем в отдельном файле для отдельного класса? Можно на примере, пожалуйста?
                                                                                                        0
                                                                                                        Например модель и её репозиторий.
                                                                                                          0
                                                                                                          какая от этого выгода?
                                                                                                            0
                                                                                                            От того, что они в одном файле уменьшается количество сущностей, которыми нужно оперировать при разработке, да и инклудов меньше будет выполняться. Минус — более сложный autoload.
                                                                                                      0
                                                                                                      хорошая альтернатива уродливому автолоаду такая:
                                                                                                      <?php
                                                                                                      spl_autoload_extensions(".php");
                                                                                                      spl_autoload_register();
                                                                                                      ?>
                                                                                                    0
                                                                                                    Хм, а это не очевидно? Имя класса дублируется. Я предлагаю хранить как удобнее и понятнее, а не повторять названия классов названия классов в обязательном порядке. KISS — что для добавления класса мне нужно создавать новый файл, помещать его куда-то, добавлять в систему контроля версий; при переименовании класса, например, следить не только за исходным кодом, но и за файловой системой.

                                                                                                    А Java за такие штуки и не любят. Я понимаю, что вопрос решается умными IDE, которые сами все создадут где нужно, и заготовки напишут. Но читать-то это IDE потом за человека не будет.
                                                                                                      +1
                                                                                                      Стоп. Так какая альтернатива то? Хранить весь код в одном файле?
                                                                                                        0
                                                                                                        Эм, а у нас что-ли 2 варианта только — либо все, либо ничего?) Либо весь код в одном файле, либо каждый класс в отдельном? Хранить так, как удобнее и понятнее. Разбивать все на модули, в модуле — от 0 до N классов (и прочих штук), а не обязательно 1.

                                                                                                        В commonjs и в python это на отлично сделано, в php с неймспейсами вроде тоже получше должно было стать (правда это уже сам не пробовал, т.к. несколько лет на php не писал).
                                                                                                          0
                                                                                                          Угу, значить «файл на модуль»?
                                                                                                            +1
                                                                                                            Да, так. При этом подходе DRY не нарушается, т.к. объединение сущностей в модуль несет дополнительный смысл. Сравните, например, подход «по файлу на класс» с тем, как бы это было написано на python (и на javascript).

                                                                                                            php/классофайлы:

                                                                                                            dashboard/
                                                                                                                modules/
                                                                                                                    BaseDashboardModule.php
                                                                                                                        class BaseDashboardModule { 
                                                                                                                            // ... 
                                                                                                                    ChartDashboardModule.php
                                                                                                                        class ChartDashboardModule extends BaseDashboardModule { 
                                                                                                                            // ..
                                                                                                            


                                                                                                            потом в глобальном контексте можно использовать ChartDashboardModule.

                                                                                                            python/commonjs:

                                                                                                            dashboard/
                                                                                                                modules.py
                                                                                                                    class BaseModule(object): 
                                                                                                                        #...
                                                                                                                    class Chart(BaseModule):
                                                                                                                       # ...
                                                                                                            


                                                                                                            а потом можно использовать так, например:
                                                                                                            import dashboard.modules
                                                                                                            module = dashboard.modules.Chart()
                                                                                                            

                                                                                                            или так:
                                                                                                            from dashboard import modules
                                                                                                            module = modules.Chart()
                                                                                                            


                                                                                                            Вариант с классофайлами без неймспейсов нарушает DRY в 2 местах:
                                                                                                            FooDashboardModule повторяется в имени файла и названии класса. Кроме того, повторяется суффикс DashboardModule, который дублирует информацию о том, что классы лежат в dashboard/modules.
                                                                                                              +1
                                                                                                              Я понял вашу мысль. В ней есть рациональное зерно.
                                                                                                              Моя практика показывает, что лучше в этом случае пожертвовать DRY в угоду KISS, а не наоборот, но холиварить не хочу.
                                                                                                                0
                                                                                                                Холиварить тоже не хочу, но все ж в упор не понимаю, какие преимущества с точки зрения KISS у верхнего варианта: там же вдвое больше кода и вдвое больше файлов, да еще и со страшными именами все)

                                                                                                                Возможно, впрочем, я каких-то деталей реализации этих подходов в php не учитываю.
                                                                                                                  +3
                                                                                                                  Ну смотрите. Вот в JS я пользуюсь тем же подходом. Да и в Джаве — тоже. В чём его преимущество? Вот я хочу найти класс Rectangle модуля Shapes. Я иду в директорию Shapes и открываю файл Rectangle. А так у меня будет файл-модуль Shapes, где мне надо будет искать класс Rectangle.

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

                                                                                                                  Ну это пара из преимуществ.
                                                                                                    0
                                                                                                    Класс в одном файле сделан для удобства:
                                                                                                    есть два класса А и Б
                                                                                                    А — абстракнтый системный
                                                                                                    Б — Наследник

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

                                                                                                    А вообще, автолоад для того и сделан чтоб искуственно управлять путями, Вы можете класть абстрактные файлы вместе с наследниками, это ничего не поломает, можете хоть по 10 классов сунуть в один файл, просто Вам надо будет как нить в дальнейшем их доставать, это уже придется реализовать самому.
                                                                                                  +1
                                                                                                  Зачем экономить файлы?
                                                                                                    +1
                                                                                                    Много файлов сложно держать в голове и в окошке файл-менеджера не помещаются :)

                                                                                                    А вообще и объективные показатели есть. Когда CMS или фрэймворк для вывода «hello world» инклудят пару тысяч файлов, то выполнение скрипта это несколько задерживает, даже при использовании кэширования диска — один файл на пару мегабайт инклудится быстрее. Правда лично для меня это оправданием никогда не было, кроме случаев когда в огромные нечитаемые куски кода собираются файлы чисто на продакшене.
                                                                                                      0
                                                                                                      Вы большинство из них не трогаете, многие файлы/классы самодостаточны. Если я скачиваю библиотеку, мне не важно сколько в ней файлов, если мне нужно что-то изменить я создаю свой один файл и наследуюсь от нужного класса, где он лежит меня уже не волнует, у меня есть свой.
                                                                                                        0
                                                                                                        Я говорю, прежде всего, о соглашениях в своём приложении. В сторонний код редко приходится лазить, согласен и какое там количество файлов не суть, главное чтобы не было конфликтов между autoload. И говорю о ситуации когда мои классы довольно тесно и однозначно между собой связаны, например, наследованием, композицией или фабричными методами, причём реализации некоторых из них весьма примитивны и не требуют больше экрана кода.
                                                                                                          0
                                                                                                          Ну если в коде только собственные файлы, то как расставлять классы — причуды автора этого кода, можно и все в одном, это не запрещено, просто из пира пошла такая традиция (один класс = один файл, название класса = путь к файлу + название класса), он раздается пакетами, может путь питона хотели эмулировать, может еще где присмотрели, я не вкурсе, но после работы с таким подходом он кажется удобным =)
                                                                                                            0
                                                                                                            Всё в одном перебор, конечно, в большинстве случаев. Посмотрел соглашения об именах — не увидел требования или даже рекомендации «один файл — один класс», только «Иерархия классов PEAR также отражается на именах классов, каждый уровень отделяется знаком подчеркивания», что, кажется, несколько другое.

                                                                                                              0
                                                                                                              Именно из-за имени Вы не сможете положить два класса в один файл, ибо их придется (потому как соглашения имен) назвать одинаково, а это нельзя делать
                                                                                                                0
                                                                                                                В соглашениях имён я не увидел ничего об именовании файлов, только именование классов нашёл. Полностью доки, правда, не читал, только выборочно по нашей теме.
                                                                                                                  0
                                                                                                                  Имя класса должно быть как_полный_путь_к_файлу_(название файла) тоесть Вы не можете положить с такой схемой два класса в один файл.
                                                                                                                  Если Вы положите два класса в один файл, то судя по схеме именования Вам придется назвать их одинаково, ибо они лежат в одном месте
                                                                                                                    0
                                                                                                                    Не нашёл я этого именно в соглашения PEAR, в других видел. Ну, да ладно, я знаю о трёх возможностях, выбирать буду по ситуации. Хорошо хоть include в php это обычный оператор, а не препроцесоор, а то сейчас бы спорили есть ли смысл разделять тело одной функции/метода на несколько файлов :)
                                                                                                        0
                                                                                                        Много файлов сложно держать в голове и в окошке файл-менеджера не помещаются
                                                                                                        а это и не нужно, есть locate/find в CLI и «Go to file… (Ctrl-Shift-N)» в IDE.
                                                                                                          0
                                                                                                          Вопрос субъективного удобства — мне проще выбирать файлы визуально мышкой, чем помнить тонкости написания их имён, да ещё для рутинных задач писать регулярные выражения, которые вводить ручками. *sh для меня инструмент для установки и запуска mc. При необходимости могу без последнего обойтись, но лишь действительно при необходимости. Хотя когда-то не понимал зачем нужны [nc,vc].com :) и, тем более, мышка. Но как-то теперь трудно без неё, может потому что скорость «зрячей» печати у меня раза в 3-4 выше слепой (200-300 vs. 70-80).
                                                                                          –3
                                                                                          Пару комментариев из серии «сравнения» и «мнения».

                                                                                          1) > Мы с самого начала договорились с вами, что пишем на PHP 5.3, а это значительно облегчает работу
                                                                                          системному архитектору.

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

                                                                                          — Если честно, то я считал и буду считать, что Скриптовый!!! PHP не создан для тяжелых сложных архитектур постоянно весящих в памяти, на нем из-за его типизации приходится очень аккуратно кодить, малыми кусками. Для тяжести и жести мне кажется Java или C# самое то + ультимейтная студия с UML. А так сам PHP чрезвычайно легок и быстр для работы с текстами, выборками БД, любыми скриптовыми обработками (то есть алгоритмы на нем приятно делать, компилятор написать например можно теоретически но не сложную систему, ввиду скриптовости и динам. типизацией), etc. Но обычно для сайтов применяется и все, что еже с ними ибо на нем можно быстро написать, а потом, если есть желание наприсать ввиде C++ либы, увелича скорость до теоретически максимальной (так делается на любых крапных проектах)

                                                                                          Коммент из серии «оценка».
                                                                                          Статья хорошая, ваш код понравился. Не скрою впервые увидел неймспейсы, спасибо буду думать куда можно это применить.
                                                                                            +8
                                                                                            >Хорошему системному архитектору достаточно UML
                                                                                            архитектор должен быть практикующим программистом. Дабы обуздать буйство воображения при рисовании UML диаграммок.
                                                                                              0
                                                                                              Ну конечно же ))), эх я удалил эту часть комента у себя, думаю что все и так поймут — оказывается не поняли ))).
                                                                                            –1
                                                                                            Абстрактный синглтон нерабочий. Совсем нерабочий. Никак нерабочий. Нерабочий начиная с обратного слеша перед get_called_class(), написанием static:: вместо self:: и заканчивая тем, что в абстрактном классе никак сделать new self() – на то он и абстрактный класс.
                                                                                              +5
                                                                                              5.3 please
                                                                                                +4
                                                                                                АААААААААААА!!!
                                                                                                Извините.
                                                                                                  +1
                                                                                                  Да не за что, рад, что Вы узнали что-то новое.
                                                                                              +1
                                                                                              Если Вам нравится FORTH балуйтесь с Rebol, где есть настоящее ядро Форт-машины, всё маленькое и крутое.
                                                                                              Не представляю как любя такие вещи, как FORTH, можно не испытывать отвращения к таким поделиям как его интерпретатор на PHP.
                                                                                              Многие пытались доказать, что PHP нечто большее, чем инструмент изначально разработанный для плевания в веб разметкой и клей для различных библиотек.
                                                                                              Так появились ущербные с рождения проекты ActivePHP, PHP-GTK и wxPHP.

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

                                                                                                +2
                                                                                                >> Покажите мне задачу
                                                                                                и тут же
                                                                                                >> ущербные с рождения проекты
                                                                                                >> плевания в веб разметкой

                                                                                                Ну и зачем Вам что-то показывать и доказывать? Вы уже свой путь выбрали, удачи.
                                                                                                  0
                                                                                                  Я этот путь прошёл

                                                                                                  До версии 5.2.1 из PHP нельзя было без глюков работать с базовыми
                                                                                                  stdin
                                                                                                  stdout
                                                                                                  stderr

                                                                                                  может быть помните разрекламированный в книге Котерова (вроде его) интересный трюк с использованием своего, написанного на php хендлера под apache,
                                                                                                  когда в качестве хендлера указывается не cgi php, а скрипт на php
                                                                                                  начинающийся с
                                                                                                  #!/path/to/php-cli
                                                                                                  #!/path/to/php

                                                                                                  а оказывается не мог PHP в таком режиме не падая работать с базовыми потоками ввода вывода,
                                                                                                  о чём тут дальше говорить
                                                                                                    +2
                                                                                                    Рассказали бы о своем пути? Было бы интересно.
                                                                                                  0
                                                                                                  Интранет сервисы, не всегда вебовские и не плюющие в веб разметкой сервисы.
                                                                                                  Отчеты удобно генерить в разных форматах из базы данных.
                                                                                                    0
                                                                                                    под вебовскими подразумевалось всё, что передаётся через http
                                                                                                      0
                                                                                                      ну отчеты у меня например в консоле генерятся, часть на php, часть на perl'е старая, и ничего, удобно и быстре менять местами чем в том же Crystal Reports.

                                                                                                      Сервис погоды у меня не по http отдаёт, обычным сокетом, крутится тоже на php.

                                                                                                      Сборщик twitter сообщений периодически запускается через cron, тоже на php, новый на ruby уже почти готов, но это лишь потому, что и фронт сайта на rails будет.

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

                                                                                                        только есть один большой нюанс, по большей части приложения написанные на php имеют короткий цикл выполнения,
                                                                                                        если вам надо написать нетривиальное приложение, которое должно запуститься и потом год работать без перезапуска, то лучше это сделать например на Python'е,

                                                                                                        потому что в основных механизмах применения PHP
                                                                                                        как модуля или как fast-cgi предусмотрен периодический перезапуск системного процесса, во избежании того что откуда-нибудь да натечёт большая лужа, дырки откуда течёт затыкают, но при таком коротком интервале времени, которое обычно отводится на выполнение PHP процессу (даже как модулю сервера) не всегда видно что стало капать и откуда

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

                                                                                                          0
                                                                                                          Согласитесь, что это проблема не языка, а его реализации?
                                                                                                            +1
                                                                                                            У PHP не было и нет устоявшегося дизайна языка, у него есть только реализация, в которой время от времени появляются фичи, ООП добавлено именно как фича или скорее набор фич, этот набор фич со временем меняется и растёт, но по отношению к языку остаётся вторичным
                                                                                                              +2
                                                                                                              Ну архитектура у языка плохая, не поспоришь с этим, начали с ориентира плохого, но простого, растут как могут, от потребностей.

                                                                                                              Но 5.3 это уже не тот совсем язык как привыкли например в 5.1 даже видеть.

                                                                                                              ООП же не панацея и не серебрянная пуля, в ряде случаев даже лишнего будет.

                                                                                                              С выходом 6ой, если внесут Unicode, избавятся от обратной совместимости с кучей старого процедурного мусора и перенесут в ООП (как сделали с DateTime) то язык получит еще больше плюсов, будет уже почти другой язык.
                                                                                                                0
                                                                                                                >>Но 5.3 это уже не тот совсем язык как привыкли например в 5.1 даже видеть.

                                                                                                                +1

                                                                                                                Именно поэтому я всегда на собеседовании спрашиваю про 5.3 Этот вопрос — самый важный детектор.
                                                                                                                  0
                                                                                                                  Про разницу 5.3.1 и 5.3.5 спрашиваете? :) Я вот на память чэнжлоги не помню, даже по фичам и могу спутать, что ввели в 5.3.2, а что в 5.3.1
                                                                                                                    0
                                                                                                                    Нет.

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

                                                                                                                        На практике же знание стандартной библиотеки не менее важно, чем синтаксиса.
                                                                                                                  0
                                                                                                                  Не хочу вас расстраивать, человек(один) который переводил PHP на Unicode благополучно забил на это дело.
                                                                                                                  Так что 6ка еще не скоро.
                                                                                                              0
                                                                                                              Может это и хорошо, что короткий, не будет при блокировки приложения лока самого сервера.

                                                                                                              В прошлом висел у меня ICQ бот на PHP, месяцами утечек не было, может это при каких-то условиях и версиях утечки были. Мне кажется в PHP всё есть для нормальной работы в режиме демона, интерпретатор написать бы нормальный его или как уже я слышал есть вполне решения пересборки кода в иные платвормы hip-hop, JVM и т.п.

                                                                                                              Про Python рассуждать не могу в силу так как знаком поверхностно с языком и предпочитаю ему Perl и Ruby.
                                                                                                                0
                                                                                                                Наиболее известная причина утечек — циклические ссылки. Относительно недавно только сборщик мусора поправили, чтобы мог корректно работать с ними. Остальные утечки, имхо, на том же уровне, что и в других языках/библиотеках, написанных на C/C++/asm, то есть баги реализации «кирпичиков», а не архитектуры в целом.
                                                                                                                  +1
                                                                                                                  Ну в 5.3 такой фигни уже нету)
                                                                                                                    0
                                                                                                                    Вроде в 5.3.0 добавили собственно сборщик мусора, а в 5.3.3 поправили его баг с циклическими ссылками.
                                                                                                                      +1
                                                                                                                      В чейнджлоге — не нашел. Насколько я помню, какой-никакой сборщик мусора был в php и до 5.3, но именно в 5.3 его сделали нормальным, а не «лишь бы был».
                                                                                                                        0
                                                                                                                        bugs.php.net/48781 — Это?
                                                                                                                          0
                                                                                                                          Version 5.3.3

                                                                                                                          22-July-2010

                                                                                                                          Fixed bug #48781 (Cyclical garbage collector memory leak). (Dmitry)

                                                                                                                          Version 5.3.0

                                                                                                                          30-June-2009

                                                                                                                          Improved PHP runtime speed and memory usage:

                                                                                                                          Added garbage collector. (David Wang, Dmitry).

                                                                                                                          php.net/ChangeLog-5.php#5.3.3

                                                                                                                          Что-там было до этого не у кого, видимо, язык не поворачивался назвать сборщиком мусора :)
                                                                                                                            0
                                                                                                                            *что там
                                                                                                                            *ни у кого
                                                                                                                            :)
                                                                                                                              +1
                                                                                                                              Ну, неважно, на самом деле. Главное, что сейчас, в последней версии, такой проблемы нет. Не так ли? ;)
                                                                                                                                0
                                                                                                                                Как вышел дебиан 6-й для меня стало не важно :)
                                                                                                                        0
                                                                                                                        Да, забыл про эту причину, спасибо.
                                                                                                                        В целом если писать аккуратно и знать о причинах, можно писать и без утечек.
                                                                                                                        Имея эдакий use strict; и всегда зная о my из Perl'а как хорошая школа может послужить и PHP кодеру.
                                                                                                            +1
                                                                                                            Зачем работать со стеком (доставать аргументы для операторов) в главном цикле? По идее, функция оператора "+" должна выглядеть как-то так:
                                                                                                            function () {
                                                                                                            					 $a = Stack::pop();
                                                                                                                                                     $b = Stack::pop();
                                                                                                                                                     Stack::push($a+$b);
                                                                                                            				}


                                                                                                            Да и реализация словаря с указанием количества используемых слов в стеке явно не универсальна — что будем делать со словами, которые могут брать со стэка разное количество слов?

                                                                                                            Да и стэка, кажется, нужно минимум два — данных и команд. Хотя, может, и ошибаюсь тут, давно ту книжку читал :) По-моему, начинать реализовывать Forth-машину нужно со слова ':', реализовав его словарь (кстати, он же кажется тоже не один может быть) у нас будет практически готов.
                                                                                                              +1
                                                                                                              Ваша реализация слова предполагает, что слово должно знать о существовании стека. Не думаю, что это хорошо, слово — это просто функция, с аргументами и возвращаемым значением. Стеком должен оперировать executor все-таки.
                                                                                                                +1
                                                                                                                Не просто должно, а обязано. Forth — это стек, слов не работающих с ним чуть меньше, чем ничего :) Слова, которые берут и кладут в стэк разное количество слов, в зависимости от, например, слова, которое лежит на самом верху, вполне реальны, та же обработка массивов — наверху длина, дальше элементы. Как будете реализовать слово, считающее сумму элементов, вводить в «палача» препроцессор, который для некоторых слов будет вытаскивать переменное число слов из стека? К тому же классическое слово, это последовательность вызова других слов и чисел, что в вашем словаре пока не вижу как реализовывать… Или на лету функции создавать?
                                                                                                                  0
                                                                                                                  Не мудрено, что не видите. Посмотрите на время последней ревизии и отправки поста -))

                                                                                                                  Но за вопросы — спасибо. Если я когда-либо вернусь к этой игрушке, обязательно на них отвечу.
                                                                                                                0
                                                                                                                Стэка определённо надо два.
                                                                                                                  0
                                                                                                                  Для чего же нужен второй, не подскажете?
                                                                                                                    0
                                                                                                                    А нет, всё правильно, достаточно одного. С математикой просто не разобрался. Сейчас вроде понял.
                                                                                                                      0
                                                                                                                      Стэк вызовов и стэк данных, не? Хотя, может я зациклен на известных мне реализациях Forth, которые почему-то все были на ассемблере :)
                                                                                                                        0
                                                                                                                        Стек он один, он же Стек. В классическом Форте, разумеется.

                                                                                                                        А для команд есть очередь.
                                                                                                                          0
                                                                                                                          Не нравится мне ваши очередь и словарь чем-то интуитивно :) Что-то очень важное упущено, по-моему, что в дальнейшем потребует серьезной переделки. Один пример я уже привёл — переменное количество слов в стеке на входе. Но и это ещё не всё :)

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

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

                                                                                                                                Неудовлетворенность — двигатель прогресса.

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

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

                                                                                                                            То, что вы написали и не форт, строго говоря.

                                                                                                                              0
                                                                                                                              Не Форт, конечно. Просто модель. С возможностью дальнейшего развития, если это потребуется.
                                                                                                                                0
                                                                                                                                Опачки… А там чуть повыше как раз был спор по поводу «Нужен ли стек в виде Singleton»
                                                                                                                                habrahabr.ru/blogs/php/114666/#comment_3702077
                                                                                                                                Выходит что и правда категорически не нужен.

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

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

                                                                                                                              Нет, так далеко я не заглядывал, я намеренно ограничил себя самыми простейшими словами. Это не Форт-машина даже, а некая ее модель.
                                                                                                                                0
                                                                                                                                Понятно :) Предупреждать надо, а то я чуть не зарылся в дебри выискивая ошибки. Но парочку уже нашёл даже по вики — допускаются дублирование слов в словаре (поиск идёт с конца) и сначала проверяется есть ли слово, а уж потом можно ли интерпретировать токен как число (слова «0», «1», «2» часто определяют на целевом языке, например на ассемблере, для увеличения быстродействия).
                                                                                                                                  0
                                                                                                                                  Хотите доступ к репозиторию? -))
                                                                                                                                    0
                                                                                                                                    Если только для последующей демонстрации на хабре «как не надо писать на php» :)
                                                                                                                                      0
                                                                                                                                      Была бы гораздо интереснее тема «как надо писать на PHP».
                                                                                                                        +9
                                                                                                                        > Во-первых они совершенно не интересуются развитием языка, на котором пишут, и вопрос «А что нового в PHP 5.3» ставит их в тупик

                                                                                                                        Наблюдать за развитием PHP все равно, что наблюдать за броуновским движением.
                                                                                                                          0
                                                                                                                          спасибо за фразу, возьму на заметку и буду троллить ей пхпшников.
                                                                                                                            +1
                                                                                                                            Нас, естественно, сразу заминусовали. Хотя даже быстрый взгляд на историю развития только подтвержадет сказанное мной.

                                                                                                                            Потому что только в РНР возможна ситуация, когда переход между минорными версиями (5.2.x -> 5.3.x) приносит фич больше, чем любой переход между мажорными версиями (что 4.x -> 5.x, что 5.x -> 6.x)
                                                                                                                              +1
                                                                                                                              Это единственное исключение, версия 5.3 — это недоношенная 6-ая, все фичи 6-ой версии на тот момент успеть сделать было сложно, а сообщество уже страдало в ожидании, потому как многие нововведения — наболевшие, как например пространства имен, нормальные анонимные функции, GOTO — и тогда собственно и выпустили версию 5.3, с половиной фич 6-ой, тех что были уже готовы, отсрочив тем самым выпуск 6-ой версии. И пхпшники целы, и зендовцы сыты :)
                                                                                                                                0
                                                                                                                                > Это единственное исключение, версия 5.3 — это недоношенная 6-ая

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

                                                                                                                                > потому как многие нововведения — наболевшие

                                                                                                                                это все отмазки :) это могли нормально назвать 6-й версией и не париться. Потому что что будет в PHP 6 никто до сих пор не знает. Да а чем говорить, у PHP до сих пор даже roadmap'а или какой-либо осмысленной стратегии развития нет.

                                                                                                                                как иллюстрация:
                                                                                                                                5.3.0 — Native closures
                                                                                                                                6.0 — closure $this support

                                                                                                                                хотя понятно, что поддержка $this в замыканиях — это фича для минорной версии, а не для неизвестно когда выходящей мажорной.

                                                                                                                                и так — на каждом шагу

                                                                                                                                З.Ы. Я сам — программист на РНР, так что эта «боль такая боль» идет из глубины сердца :)

                                                                                                                          0
                                                                                                                          А вы случайно не забыли стек R, декларацию новых слов и макроподстановки? А то получился не форт, а овердизайнед
                                                                                                                          RPN-калькулятор.
                                                                                                                            0
                                                                                                                            Вы серьезно думаете, что за 3 часа я бы успел это все реализовать, протестировать и написать статью на хабр?
                                                                                                                              0
                                                                                                                              На PHP — вероятно, нет. На правильно выбранных инструментах — да.

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

                                                                                                                                Какой инструмент я был должен выбрать для этой задачи? Brainfuck?
                                                                                                                                0
                                                                                                                                Форт и интересен тем, что позволяет создать минимальную Форт-систему из ничего за очень короткое время. Под неизвестную (но не слишком извращённую) архитектуру она пишется за пару ночей.
                                                                                                                              +4
                                                                                                                              Эх, php-php как же это уродливо выглядит:
                                                                                                                              $args = \array_slice(..)
                                                                                                                              >_< ну зачем же приняли "\" в качестве разделителя для namespace.
                                                                                                                                –1
                                                                                                                                Ради контекстной независимости, очевидно.
                                                                                                                                  +1
                                                                                                                                  ну я как бы про то, что символ выбран неудачно, в этих C++/С# чудесное "::", в Java ".". Нет ну честное слово это выглядит лучше
                                                                                                                                  food::soup и java.lang.String чем 
                                                                                                                                  
                                                                                                                                  чем
                                                                                                                                  \FORTH\EXCEPTIONS\SYSTEM\NamespaceIsWrong();
                                                                                                                                  , Но это только моё личное мнение.
                                                                                                                                    0
                                                                                                                                    И "::" и "." уже были заняты как бы.
                                                                                                                                      +1
                                                                                                                                      ну как бы они и в Java и в C++ тоже как бы заняты "::" для доступа к статическим методам/свойствам. "." для аналогичных целей в Java (для дотупа к обычным методам/свойсвам тоже)
                                                                                                                                        0
                                                                                                                                        Вы немного несравнимое сравниваете.

                                                                                                                                        Никогда не думали, почему в PHP числа складываются "+", а строки конкатенируются "."? Зачем два разных оператора, если, например, JS обходится одним "+"?
                                                                                                                                          +2
                                                                                                                                          сравнимое сравниваем. емнип, символ \ был выбран, потому что лень было возиться с парсером.
                                                                                                                                            0
                                                                                                                                            То есть ответ «нет, не думал».
                                                                                                                                              0
                                                                                                                                              Неверный вывод.

                                                                                                                                              Для слаботипизированного языка просто обязательно иметь два разных символа для конкатенации строк и складывания чисел. Это — очень грамотное решение со стороны разработчиков РНР.

                                                                                                                                              К вопросу о выборе символа для namespace'ов это не имеет отношения.
                                                                                                                                                –2
                                                                                                                                                Ну и ровно также нужно иметь два разных символа для обозначения статического метода или свойства и неймспейса.

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