Pull to refresh

Comments 177

угу.
Причем не такая что-бы совсем уж сложная штука.
Вообще это единственная фича которую очень жду еще с 5.1, а всё придумывают кучу не особо нужных наворотов.
Не понимаю почему не взяли.
Вам, батенька, тогда нужно писать программы на шаблонизаторе каком-нибудь. Зачем вам язык программирования? — это слишком сложно — куча бесполезных фич. Присмотритесь к JADE, HAML — в них нет ненужных наворотов.
Думаю, основная проблема не столько в реализации, сколько в определении поведения. Есть некая function(int $i) — что должно быть при попытке передачи ей строки или null — ошибка или приведение? Для нескаляров, особенно для объектов, логична ошибка, а для скаляров (да и для массивов) я бы предпочел приведение. Но это будет ещё одна вещь в PHP, которая «это невозможно понять, это нужно просто запомнить». А если выбрать ошибку, то очень много кода сломается из-за добавления в сигнатуры функции/методы типов аргументов, поскольку приведение они используют (явно или нет — не суть) в теле.
Владимир, никто не говорит о том, что должна быть жесткая типизация.
Это должно быть опционально. Я рассматриваю это как синтаксический сахар, который должен спасать от:

assert('is_int($int) /* $int parameter must be an int, not just numeric */');

Хотя когда пишешь с включенным стрикт, то оно как-то… в общем мозг почему-то решает что я вернулся в язык с жесткой типизацией и т.п., упорно пытается пропихивать указание типов.
Утверждения не должны использоваться в обычных операциях, таких как проверка входных параметров.
:)
Но в целом я согласен, что «мозг решает». Но в частностях он может закрывать глаза и считать что метод UserStorage->findById($id) вполне может принимать $_GET['user_id']. Этот метод сам должен учитывать возможность передачи ему строки — в PHP по умолчанию всё строки :)

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

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

Что касается приведения типов, то опять таки — а если мне класс какой дадут, или массив. Тоже приводить к числу? Или как мне указать что параметр скалярный? :)
С красивым сообщением по соображениям безопасности — это валидация :)

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

Ага, к числу :) Объект (у которого не реализована __toString) или не пустой массив — к 1 :) Кстати, даже текущая реализация тайп хинтинга не гарантирует, что вы в функции/методе получите объект «хинтингового» типа — может быть передан null, который является отдельным типом.
если NULL использовался как значение параметра по умолчанию, то это будет также допустимо в качестве аргумента для последующего вызова.

А так по идее должен ругаться.
Угу, но пропускает.
хм… интересно, никогда не проверял. Доверял документации. Спасибо.
Я просто оставлю это здесь
php 5.4
class A {  function foo(B $b) { var_dump($b);  } }
$a = new A();
$a->foo(null); // Catchable fatal error: Argument 1 passed to A::foo() must be an instance of B
$b = null;
$a->foo($b); // Catchable fatal error: Argument 1 passed to A::foo() must be an instance of B
Очень странно. Точно помню, что проверял такую возможность.
class A { function foo(B $b=null) { var_dump($b); }}
$a = new A();
$a->foo(null); // NULL
$b = null;
$a->foo($b); // NULL

Значение по-умолчанию NULL.
5.2.17 и 5.3.13 тоже самое.
это невозможно понять, это нужно просто запомнить

function foo(int n)
function foo(int! n)
function foo(int+ n)
Чем не вариант?
Чёрт, трёх голосов не хватило. :( Надо было подкупить.

Я ещё про лямбды мечтаю (краткий синтаксис для записи замыканий). Но фиче-реквест (с патчем, кстати) развернули даже на стадии задачи в багтрекере. :(
Угу, лямбды тоже бы пригодились :( (у них вообще странный подход к развитию языка — добавляют только то что нужно самим и полностью кладут на мнение пользователей, но при этом общего направления просто нет).
Общее направление было озвучено: язык должен оставаться понятным даже новичку. Ждать что-то умного не стоит.
Вы и правда считаете что генераторы понятнее чем getter-ы и setter-ы? (кстати, а что по-вашему в них непонятного?)
Это нужно спрашивать разработчиков PHP core. Не помню точно было ли это про getter-ы или генераторы, но кто-то из них сказал, что язык должен оставаться понятным. Как генераторы попали в релиз не знаю %)
Прошу прощения, отчего то показалось что вы на их стороне :)
Надо было на хабре что ли написать. Один голос точно бы был :)
Да, но тут все-таки функционал есть. Чуть менее красивый синтаксис, но реализовав на магических методах родительский класс мы не сильно ограничены в функционировании. А вот с типами реализаций нет.
Есть некая разница между «геттеры для всех private» и «геттеры для определённых private». Так-то тоже чистый сахар. Но сделать код чуть более структурированным помогло бы, конечно (в отличие от __get).
С помощью __get это тоже реализуемо, для чего __get должен перевызвать соответствующий геттер, если он существует.
Магические костыли здорово усложняют рефакторинг кода :( (это даже если не вспоминать о Indirect modification of overloaded property has no effect)
Чем осложняют? Какая разница — будет ли геттер вызван ядром или __get объявленном в родительском классе?
По сути тут четыре минуса:
1- сложности с перегрузкой магических методов. Ну так они и так костыли. Как по мне, так их место именно в базовых классах, а не в прикладных. Ибо нефик. Но да, нудобно.
2 — Синтаксис менее красивый. В предложенном синтаксисе методы группируются в одну группу, и так их лучше видно. — Ну тут такое… Да, неудобно. С другой стороны меньше синтаксических конструкций, меньше путаницы для новичков. Не то чтобы это было серьезным аргументом, но и красота оформления геттеров тоже не сильно весомый аргумент :)
3 — Придумывание магических схем для работы геттеров накладывает некоторые ограничения в именовании этих самых геттеров. Какой вариант именования выберешь, такой и будет, но у любого из них есть ограничения. Хотя я пока не придумал случая когда бы это мешало.
4 — Хуже производительность. Плохо да. Вообще нечего сказать. Разве что то, что разница должна быть несущественной.
Чем осложняют?

Нет возможности их рефакторинга, более того даже для автокомлита нужно их все прописывать руками в docblock-е класса (совершенно в другом месте => легко забыть, легко перепутать и т.д. и т.п.).

Какая разница — будет ли геттер вызван ядром или __get объявленном в родительском классе?

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

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

Что-то я постоянно вижу обратное — хрен поймешь что и где они изменяют :(
C докблоком класса а не геттера да, согласен. Тут есть сложности.
Чем осложняют? Какая разница — будет ли геттер вызван ядром или __get объявленном в родительском классе?
По сути тут четыре минуса
Усложняют — кто ж спорит. И недостатки есть. Но исходное утверждение о чём было? О нерешаемости задачи в предыдущих версиях языка, что на деле — не так, задача решаема. Так же как с помощью этой магии можно и миксины реализовать, которые в языке ещё не скоро появятся, если вообще. Цена вопроса — вопрос отдельный и подлежащий всестороннему рассмотрению и тщательному взвешиванию.
можно получить элемент массива сразу момент его объявления

Не могу себе представить, для чего это может быть нужно. В большинстве известных мне языков нет разницы, откуда получено rvalue-значение — константа, переменная, конструкция языка, вызов функции. В PHP же пришлось делать отдельно поддержку func()[idx], отдельно ($a ? $b : $c)->property и вот теперь зачем-то сделали такую же отдельную поддержку для индексации констант. Судя по всему, грамматика у них написала бессистемно.
$retcode=ext_api_call();
echo [RET_SUCCESS=>'SUCCESS',RET_ERROR=>'ERROR'][$retcode];
Ну да, только если заменять switch. Хотя на месте дизайнеров языка поощрять такой подход я бы не стал — массив создается каждый раз заново, да и слишком похоже на антипаттерн magic constants.
Зато позволяет в простых случаях не городить огород из кейсов.
Имхо логичнее было бы использовать pattern matching для таких случаев. Не удивлюсь, кстати, если в одной из следующих версий его внезапно допилят, с каким-нибудь экстравагантным синтаксисом :)
Хардкод литералов — очень плохо. Вообще, подобный подход снова пахнет плохо поддерживаемым индокодом.
Не могу себе представить, для чего это может быть нужно.

Это нужно постоянно. Наверное 90% fatal error в моих первых программах на PHP (после C/C++ в основном) заключалось в отсутствии этой «фичи».
Судя по всему, грамматика у них написала бессистемно.

Для кого-то это новость? Вообще формальной грамматики в PHP отдельно от транслятора нет.
Это нужно постоянно.
Ну и ничего, переучились же впоследствии? Стремиться к краткости записи, используя неочевидные свойства языка — не самая лучшая практика. Очень быстро выходит боком при необходимости быстро разобраться в том, что делает написанный хотя бы полгода назад код — особенно, если на тот момент вы только начинали изучать язык.

Вообще формальной грамматики в PHP отдельно от транслятора нет.
Только что посмотрел — таки есть, но там все и правда печально.
Дело в том, что я считал подобными свойства языка очевидными. И каждый раз читая про очередной дереференсинг с одной стороны я рад, а с другой возникает раздражение «ну когда же вы сделаете обычный rvalue и операторы типа [] или -> реально операторами, а не отдельным элементом синтаксиса».

Она не отдельно от транслятора, как я понимаю по урлу. Понятно, что у транслятора она есть.
«Очередной дереференсинг» напоминает недавнюю статью про самописный язык программирования, где доступны только 3 переменные — A, B, C, но в новой версии автор обещал добавить переменную D…
В точку :) А что за статья? Как-то пропустил.
Судя по всему, грамматика у них написала бессистемно.
Это не говоря уж о такой штуке как:
empty() можно применять к результатам функций или выражений без необходимости сохранять этот результат в отдельную переменную
Реально как это вообще можно было сделать, чтобы отдельно взятые конструкции выборочно работали с разными rvalue. Какое уж тут бессистемно, это какой-то абсурд вообще)
Я так понимаю, оно изначально вообще для другого задумывалось )
Жаль. думал Многопоточность прикрутят из коробки. Видимо не судьба увидеть нативные потоки CreateThread.
Пхп интерпретируемый скриптовый язык, какие потоки.
Ну да-да-да, а это какже?
Питон и руби, так-то тоже интерпретируемые языки, но треды в них есть.
Естественно, есть такой функционал (как мы видим, в бибилиотеке PECL). На хабре даже были статьи на тему использования pthreads. Но.
Главная проблема пхп в виде демона состоит в том, что он не деаллокатит занятую раднее память. Если один раз пикануло, то в памяти у вас будет висеть жиртрест, использующий малые проценты от аллокаченной памяти.
Он кстати память нормально освобождает, главное помнить, что новый gc не всегда хорошо разруливает цепочки оюъектов и довольно-таки сложные циклы ссылок. Помогало ручное освобождение unset'ом там, где нужно.
Немного не так, внутри процесса, GC работает на ура. Но сам процесс не отпускает откушанную у операционки память.
Разве? Вроде казалось, что отпускает после обработки скрипта. Или вы про чисто режим демона скрипта, а не mod_php или php-fpm?
А в каком контексте, как правило, упоминается необходимость использования потоков? В большинстве случаев в контексте создания сервера\демона. Другие сценарии с функционалом пхп малосостоятельны.
Меня давно (больше 10 лет) интересует возможность создания веб-страниц (то есть синхронных по сути программ) на PHP с возможностью параллельной обработки инфы, например одновременной закачки с нескольких удаленных серверов.
костыль, при котором контекст пропадает.
по сути речь шла не о костылях, а том что PHP из коробки не работает с мультипоточностью.
Слово «например» было не случайно.
WaveCut не могли бы вы дать ссылки и пояснение касательно pthreads.
Как она работает какие системные вызовы вызывает ??

Она дочерний процесс не запускает ??
В общем полезно было бы услышать How-to manipulate Threads in PHP.
В какой то степени они есть но Вопрос pthreads создается в пределах процесса, или это обманка ??
Как я понял pthreads это не потоки которые запускаются в пределах процесса.

А костыль процесс POSIX который каким то образом имитирует поток.
А signal-based архитектура, очереди всякие и gearman тут не помогут?
Помогут, но это будут костыли и/или оверхид для простой в принципе задачи. И как не крути, то столкнемся или с лишними процессами, или с ожиданием результата одной операции для начала другой. Альтернативой могли бы быть асинхронные операции ввода-вывода, типа как в nodejs но их тоже из коробки как бы нет.
А впиленные корутины не помогут?
Был бы (простой) асинхронный ввод-вывод типа fread_async — помогли бы, а так сахар, основной проблемы (остановка исполнения на время блокирующей операции, даже если последующие от неё не зависят) не решающий.
Вот и соль. Толку от мультизадачности нет, ведь I/O синхронное.
Были бы потоки — можно было бы не переживать о синхронности I/O — запустил штук двадцать параллельно и пускай ось переживает.
[zanuda_mode]
Язык программирования не может быть интерпретируемым или компилируемым. Могут быть разные его трансляторы — интерпретаторы и компиляторы. И то, грань между ними стирается — вроде бы компиляторы (C#, Java) компилируют исходники лишь в байт-код виртуальной машины, которая потом она интерпретирует, а вроде бы интерпретаторы (включая референсный PHP) тоже, по сути, компилируют в байт-код виртуальной машины.
Ну там же, в исходном моем сообщении, еще присутствует такая характеристика, как скриптовый. Не стоит придираться к вырванному из контекста слову, в комплексе все становится куда прозрачнее :)
Вступление из статьи на вики
Сцена́рный язы́к (англ. scripting language, в русской литературе принято название язык сценариев) — высокоуровневый язык программирования для написания сценариев — кратких описаний действий, выполняемых системой. Разница между программами и сценариями довольно размыта. Сценарий — это программа, имеющая дело с готовыми программными компонентами[1].
Согласно Джону Устерхауту, автору языка Tcl, высокоуровневые языки можно разделить на языки системного программирования (англ. system programming languages) и сценарные языки (англ. scripting languages). Последние он также назвал склеивающими языками (англ. glue languages) или языками системной интеграции (англ. system integration languages). Сценарии обычно интерпретируются, а не компилируются[2], хотя сценарные языки программирования один за другим обзаводятся JIT-компиляторами[3][4][5].
В более узком смысле под скриптовым языком может пониматься специализированный язык для расширения возможностей командной оболочки или текстового редактора и средств администрирования операционных систем[6].
PHP никак не напоминает язык для «кратких описаний действий, выполняемых системой». Большая часть стандартной библиотеки — это лишь биндинги (с учетом специфики типа resource или object вместо числовых дескрипторов) к обычным системным либам. По сути PHP — это динамический форк «C с классами» и предопределяемыми глобальными переменными.
Но пхп и не системный ЯП, никак. Все что делает программа на пхп это
  1. Принимает входные параметры
  2. (magic)
  3. Выводит результат

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

А по вашему определению и ls или grep типичный скрипт, хотя написаны на «нескриптовом» языке.
Я сам PHP-разработчик, люблю его и прекрасно знаю, что умеет язык, насколько он могуч, это и написано в моей схеме выполнения под пунктом 2 :)
Но чем кончаются подобные пути его использования и чем они осложнены я написал в предыдущей ветке, чуть выше.
К сожалению, к великому сожалению, он для этого не предназначен.

Да и проблема надумана. Многопоточность в сложных системах на пхп рекрасно решается в рамках нескольких процессов. Нужен тред? Запускаем его отдельным процессом — и волки целы и овцы выполняются.
Ну да, предназначен он по сути для работы в режиме CGI для HTML вывода — для этого в него внедрено куча фич, начиная с тега <? ?> — кстати, даже поэтому, имхо, он не может считаться скриптовым языком. Но фич, свойственных ЯП общего назначения (ЯПОН :), у него никто не отнимал, более того они постоянно добавляются.

Форкаться можно, но есть проблемы свойственные форкам — разные адресные пространства.
Соответственно и получается ситуация, когда — форк — правый костыль, демон — левый костыль, но одновременно можно работать на одном из них и многопоточность на пхп слегка хромает. А иначе никак, CGI же.
Ну прикрутят такие как в питоне или руби, с GIL, не дающим 2м потокам одновременно занимать процессор. Мало задач в которых они действительно нужны.
GIL'ом больны не все реализации питона и руби.
Статья про CPython и про некорректный хак к нему, «избавляющий» от GIL. Но кроме CPython есть IronPython (Python на .NET), Jython (Python на JVM) и ещё целый зоопарк реализаций, в которых GIL нет. У альтернативных реализаций есть некоторые особенности и недоработки, но они вполне полноценные (IronPython, например, работает быстрее CPython в подавляющем большинстве тестов).

То же касается руби.
Молоток — для забивания гвоздей. Если вам нужны потоки, то вам нужен не PHP.
Объективные обоснования у Вас есть?
Т.е., если нужно в приложении добавить небольшой модуль с потоками (не могу сходу придумать пример), нужно делать его внешним приложением на другом языке или даже переписать всё приложение целиком? :)
Пример — авторизоваться на нескольких сайтах от лица пользователя и прочитать сообщения/уведомления. Учитывая, что сетевые задержки весьма внушительны, а процессы дороги, хорошо бы это делать в потоках.
Спасибо за наводку, пороюсь на досуге, но судя по
$response = $request->send();
это не то.
Да, там блокируется выполнение, если вы об этом. а дальше все на callback'ах
Можно пробовать комбинировать с очередями
Если модуль небольшой и вас не смущают костыли — дерзайте, по-моему, на PHP потоки можно прикостылить уже сейчас.

Я про случай, когда во всём веб-приложении постоянно нужны потоки, когда нужна честная многопоточность, когда размер приложения делает костыльное программирование очень нежелательным. В этом случае я бы рекомендовал изучить другие варианты.
Обновлена библиотека GD, в частности появилась поддержа WebP
В каком смысле «появилась»? Она там была (http://bolknote.ru/2012/08/16/~3716/), может по-умолчанию включена теперь?
>Удалена поддержка Windows XP и 2003
Почему именно сейчас? о_О Нововведения вроде незначительны.
Избавляются от легаси говнокода в ядре?
Кстати, а что это означает — ">Удалена поддержка Windows XP и 2003"?

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

p.s. То, что проблема с запуском — это я убедился. Попытался в Денвер подставить php 5.5 — ругается, не может запуститься (5.14.* работает норм). Хочется просто почитать — почему так…
Не знаю. Видимо использует какие-то вызовы, которые в NT 6 появились, а в более ранних нет.
Тут уже предполагали, что это вопрос отказа от старых костылей. Т.е. при рефакторинге ядра нужно было или переписывать куски кода для работы с ХР и 2003 заново, или выкинуть. Поленились, решили выкинуть. В принципе правильно. К тому времени когда 5.5 станет стандартом, а не частными применениями эти ОС более-менее отойдут. Т.е. кому нужен старый комплект, тот и так будет сидеть на старых версиях пхп, а кто будет впереди, у того с высокой вероятностью будет и ось помоложе.
Понятное дело, что если они не переписывали заново, то выкидывать то что работает глупо. Я например еще долго буду сидеть на 2003/ХР, а поиграться с 5.5 мог бы.
Возможно, что не при рефакторинге, а в процессе введения новых фич лень было писать отдельный код для XP и удалили его нафиг.

А может чисто политика — не поддерживать не поддерживаемые оси и расчет, что 5.6 не успеет выйти, ло полного прекращения поддержки со стороны МС.
А что там на счет APC? Меняем кешеры на сайтах или будут решения?
UFO just landed and posted this here
А половина сайтов до сих пор работают на php 5.2. Доля даже 5.4 минимальна. :( Где-то на днях видел статистику.

Важно: mysql теперь официально depricated — будет выдавать notice при соответствующих настройках! Думаю стоит добавить в топик.
5.2 на 5.3 вообще не сложно перевести и не будет никаких проблем (особо). Не понятно, почему не обновляются.
Отчасти, наверное, потому что владельцы сайтов либо не подозревают о такой возможности вообще, либо не могут провести аудит (как бы) своего кода на предмет совместимости — знают что обратная совместимость неполная, но даже видя список несовместимостей не могут сказать используется они в коде или нет.
Мы переходим на каждую версию, но каждый раз везде ловим глюки, сегфолты и лики. Если честно, стабильность не очень )
Если посмотреть чейнджлог, то у них там в каждом даже самом маленьком релизе по три-пять сегфолтов, пару ликов и всякие критикалы чинятся.
Многие — из-за проблем с Zend Optimizer'ом.
Теперь у хостеров будет повод обновиться до 5.3 :)
Предыдущий мажерный релиз 5.4 был выпущен чуть больше года назад (1 марта 2012 года), а 5.3 аж в 2009 году (30 июня) — легко заметить, что разработка PHP наращивает темп!

Легко заметить что перечисленных временных отрезков не достаточно, чтобы выводить какие-то закономерности.
Между 5.3 и 5.4 ещё «был» 6.0, так что выделять закономерности вообще нелогично.
Кстати, а поддержка 5.3 прекратилась в связи с этим или теперь три поддерживаемых релиза?
Класс! Теперь хотя бы будет (усилится) аргумент против 5.2: «это не просто старьё, а мегастарьё — вы ещё на PHP 4 предложите проект писать» :)

Ну а так, добавить к «Good bye 5.3, you were a great step for PHP!» нечего. RIP. Но теперь хотя бы можно не писать array() в публичном коде :)
А я не очень понимаю на счет empty() — это получается языковая конструкция, а не функция?
То есть функция должна же выполняться последовательно:
a(b()); — сначала вызовется b, затем ее результат отправится в a
Это была языковая конструкция по сути. Типа функция, принимающая только ссылочные типы. Теперь обычная функция, работающая по значению.
это мягко сказано — «монструозных»
Про empty() приятно, давно хотелось.
еще бы empty() поддерживала не ограниченное число параметров как isset, то тогда вообще вообще цены бы не было.
По принципу OR или AND? Я не использую isset с несколькими параметрами как раз потому, что каждый раз когда встречаю такое использование, то приходится лезть в мануал.
AND, хотя с другой стороны эта хотелка как AND, так и OR легко реализовывается функцией прослойкой при помощи func_get_args()
Как себя ведёт Zend Optimizer под fastcgi/fcgid, создаёт количество кэшей равное количеству воркеров (как APC, который годами это не исправлял), или один кэш?
Какое хранилие взамен APC теперь посоветуете, без вышеозвученной проблемы? Memchage/Redis избыточны и медленны по сравнению со старым APC.
Кстати почему не добавят Igbinary в php из коробки? Почему вообще кэшеры не могут сохранить скажем простой массив без серилизации в shared memory?
Да, убер-полезная функция, в 10 строк реализуется.
в C++ есть STL. Я не думаю, что ребята, программирующие на С++, в каждой программе вручную пишут стеки / списки / карты и т.п. Но, конечно, это моё личное убеждение
Не уловил связи между добавлением стндартной функции array_column для массивов в PHP и велосипедной реализацией контейнеров вместо использования STL в C++. Вообще не уловил.
Хорошо, попробую объяснить по-другому. Вот, к примеру, задачка:
Есть массив с элементами вида somethingN.ending, т.е:
<?php
$arr=[
    'something1.ending',
    'something2.ending',
    'something3.ending',
    #To be continued ...
];
?>

Предположим, нам надо убрать у всех элементов окончание (т.е. '.ending')
Исходя из вашей логики, вместо
<?php
foreach($arr as &$v)
  $v=basename($v,'.ending');
?>

Следует писать так:
<?php
foreach($arr as &$v)
  $v=substr($v,0,strrpos($v,'.ending'));
?>

У нас соревнование? Чем больше ненужных функций использовано, тем круче программист?

Ещё из того же жанра мне нравится:
<?php
if($something)
    return true;
else
    return false;
?>

Казалось бы, зачем тут else?

То есть, я хочу сказать, что незнание возможностей из коробки и желание втиснуть побольше воды в код, — в основном, порождает говнокод. Незнание возможностей языка — это не есть хорошо.
foreach($arr as &$v)

Так писать не надо: такая процедура «ломает» массив. Если очень хочется, то вызов unset обязателен.

$v=basename($v,'.ending');

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

$v=substr($v,0,strrpos($v,'.ending'));

Так писать не надо:
1) strrpos может вернуть false. Если предполагается строка с заданным окончанием, то правильнее выкинуть ошибку.
2) Подстрока может находиться не в конце строки. В этом случае также правильнее выкинуть ошибку.
3) За экономию на пробелах расстреливать надо.

Казалось бы, зачем тут else?

Неправильный вопрос: если убрать ветку else, то логика конструкции изменится.

Надо заметить, что приведённый вами книжный пример индусского кода if-true-false — единственный код, который работает правильно, и при этом не настолько уж затрудняет чтение.

В общем и целом. Вы сравнили очередную очень ограниченную и безсистемную функцию со стандартизированной библиотекой STL. Как аргумент привели использование функции для работы с именами файлов на строке, не являющейся именем файла. Ещё всунули ни к селу ни к городу книжный пример индусского кода. Простите, конструктивный диалог с вами невозможен.
Мне тоже не хочется дискутировать с человеком, который придумывает сам себе вопросы, сам же на них отвечает в комментарии под совершенно другой задачей.

1. Что значит ломает? С каких это пор мне нельзя использовать ссылки в foreach? Зачем мне unset? Я же дальше нигде не использую $v… О, Боже, я же не просил раздувать из учебного примера машину Голдберга. Вопрос был совершенно в другом, а не в «Найдите все уязвимости, сверстайте шаблон и научите скрипт заваривать кофе по утрам».
А я бы расстреливал людей, которые пишут пробелы после каждого знака и обрамляют фигурными скобками всё, что угодно, даже если в условии (или цикле) выполняется всего одно выражение.

Про удаление ветки else — никто не заикался. Была речь о слове else. Чем читаете вы и люди ниже — я не знаю.
3) За экономию на пробелах расстреливать надо.
Ой подписываюсь, ой больная тема.
Ещё из того же жанра мне нравится:

<?php
if($something)
    return true;
else
    return false;
?>



Казалось бы, зачем тут else?


Простите, а какой вариант предлагаете Вы?
Единственное понимание ваших слов которое мне приходит в голову — настолько ужасно, что боюсь сразу критиковать — а вдруг зря человека обижу…
Теперь можно и return boolval($something) :)
Я не понимаю к чему эти комментарии и зачем вы приводите к булеву типу $something..., но допустим $something — SimpleXml Object?
Ваша функция возвращает boolean независимо от типа $something. В новой функции, если не приводить $something к boolean, возвращаемое значение может иметь другой тип.
Я сражён и вашим комментарием и теми что, ниже…
Вам не кажется, что $something и true чем-то отличаются? Если мне не нужно возвращать $something, а я хочу именно true, то что?

Народ, вы либо устали, либо серьёзно считаете, что писать else после return это нормально? Какой смысл ставить else, если return возвращает результат и код дальше не исполняется?
Народ, вы либо устали, либо серьёзно считаете, что писать else после return это нормально? Какой смысл ставить else, если return возвращает результат и код дальше не исполняется?


Это почему это не исполняется?

P.S. Вообще, я за один return в конце метода. Остальное чаще всего от последователей индуизма.
<?php
$a=7;
if($a==5)
    return true;
else
    return false;
?>

Ммм, вы действительно считаете, что здесь необходимо ключевое слово else? Попробуйте его убрать — увидите, ничего фатального не произойдёт, только код станет короче.
Да необходимо. Если убрать else, то возвращаться будет null, а не false — это «две большие разницы».
Я убрал, возвращет false. ЧЯДНТ?
<?php
$a=7;
if($a==5)
    return true;
return false;
?>
Ну слава яйцам. Ваш вариант таки просто непрофессионален, как я думал изначально.
Просто после некоторых ваших слов я заподозрил, что вы совсем языка не знаете…

Итак по вашему говнокоду:
Так писать нельзя.
«Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живёте». Мартин Голдинг.

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

Два ретурн это плохо. Подряд — вдвойне плохо.
Писать иф/елсе без фигурных скобок — зло. Сам иногда грешу, и каждый раз на себя ругаюсь.
Но если даже и писать без скобок, то тот код который вы раскритиковали — был читабельным. Ваш надо гадать. И да, самую длинную кнопку почаще нажимайте…
Почему нельзя ставить два return? Кто-нибудь может адекватно объяснить? Конкретно с аргументацией, а не «не ставь два return — это плохо»… Что плохо? PHP — это не C++, тут народ ещё говорит о каких-то type hinting'ах. В чём проблема — берите C и будет вам контроль типов.
Тоже, я смотрю много «профессионалов» и «знатоков своего дела», которые считают, что Singleton это плохо, отвратительно и вообще от него мир рушится, но нигде я не увидел ни одного конкретного аргумента / упоминания / примечания, почему Singleton так ужасен…

«Писать иф/елсе без фигурных скобок — зло». Вот оно как? Ну, понимаете, речь идёт уже о неспособности читать нормальный код. Если вы не различаете, что выполняется в условии, а что вне его, то я могу только посочувствовать.
<?php
if($something)
    DoSomething();
DoFinally();
?>
Единая точка выхода удобна как для чтения, так и для рефакторинга.
Часто приходится делать небольшие дополнительные манипуляции перед отдачей ответа.
Да и относительно линейная структура кода сильно повышает его читабельность.

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

Читать можно и брейнфак. Нужно ли?
Прочитать можно любой говнокод. Даже ужаснее чем ваш.
Но я в детстве всегда старался избежать ассемблера, и выносить туда только низкоуровневые вызовы и очень узкие места. И даже беря чужой код на ассемблере я часто переписывал то, что не критично на языке более высокого уровня, чтобы было читабельнее.
Поэтому мне вас не понять. Ладно бы говнокодил себе по тихому. С кем не бывает. Я вон и сам постоянно выдаю такой говнокод, что каждую строчку приходится комментировать… Но я же не кричу об этом на каждом углу, и не агитирую за то, чтобы все говнокодили…

UPD: про иф забыл. Я за скобки в первую очередь потому, что в половине случаев потом все равно приходится их ставить. Ну и для единообразия и читабельности тоже будет полезным.
То есть — когда в логике нет ненужных конструкций / операторов — это теперь называется говнокодом? Куда катится мир…

Может мы ещё обойдёмся без ООП, будем везде статические методы писать для «единообразия и читабельности», а лучше, пожалуй, вообще обойтись без условий и циклов, зачем писать говнокод, если можно 5 строк раздуть на 500.

UPD. Леонид Аркадьевич расстроен текущим положением дел.
То есть — когда в логике нет ненужных конструкций / операторов — это теперь называется говнокодом?

Отчасти. Смотря что считать «ненужным». Краткость и совершенный код плохо совместимы, хороший код почти всегда содержит избыточные с точки зрения синтаксиса и алгоритма элементы. Даже в вашем примере есть пробелы, переводы строк и т. п. — они же не нужны по идее, можно в одну строку записать и не использовать пробелы там, где без них можно обойтись.
Полгода опыта (или 5 лет опыта в вебстудии им. Васи Пукина) детектед.
всегда приятно услышать мнение профессионала
Ок, по пунктам:
1. Один return: Помогает увеличить читаемость кода, упрощает тестирование, показывает, что код хорошо декомпозирован (а это одно из необходимых условий качественной архитектуры). Я, конечно, против правила про 5 строк на метод, но и 40 строк на метод считаю приемлемыми лишь в исключительных ситуациях.

2. Singleton: Порождает глобальную зависимость на один инстанс. Если вы знакомы с юнит-тестами, с системами, использующими несколько различных сервисов одного класса (стандартным примером может являться использование различных видов хранилищ в одной системе: файлы, несколько бд с разным соединением и т.п.) и с понятием stateless, то объяснять вам не придётся. Если ещё не знакомы — что ж, в данный момент вы находитесь на «синглтон — это круто» части своего пути :)

А про работу в команде вам уже написали. Синглтон и множественные возвраты тоже из серии про эгоизм разработчика.
Ок, по пунктам:

Сегодня писал прототип. Даже скорее прототип концепта. Раза два или три применил множественные возвраты. Вспомнил этот спор. Обратил внимание что они пришлись аккурат на самые говнокодистые методы. Прям аж физически ощутил всю кривизну, которая вынудила меня писать именно так…

А вот с синглтоном я так и не придумал как мне без него обойтись в конкретной ситуации. :)
Передавать параметром.
Володь, не пройдет. Синглтоном у меня идет класс шаблонизатора. И не нормального шаблонизатора, который с шаблонами, а такого который всё генерирует через ДОМ. Ну а основной ДОМ документа по любому должен быть в одном экземпляре. Есть вариант только хранить его в стат.переменной класса.
Но это имеет те же сложности что и у синглтона.
Вариант передачи состояния параметром это стрем какой-то выходит… его же еще получать надо, передавать как-то… в общем двукратное усложнение кода ради просто ухода от синглтона.
«Всё мне позволительно, но не всё полезно» ©

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

if($something)
    DoSomething();
DoFinally();


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

Разумеется, если мы пишем никому не нужный «hello, world» на три строчки, то нам в целом это всё пофиг, всё перед глазами и очевидно. Но в серьёзном практическом применении код имеет свойство со временем «разбегаться» на десятки строк, между которыми ещё и комментарии по разным поводам; то, что было — со временем забывается, в команде меняются люди, и всё становится уже очень не очевидным. return вполне может оказаться за пределами экрана, условие вполне может оказаться нетривиальным, чтобы с лёту вычислить пойдёт управление дальше или нет и может потребовать обращение к другим источникам. Всё это время и усталость.

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

«Аврал… как много в этом слове...»

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

Да, все мы были детьми и новичками, в чём-то мы оказываемся новичками или дилетантами каждый день — жизнь широка и сложна. Но не стоит отстаивать дилетантскую позицию из любви к самомнению. Признак мудрого человека — готовность учиться в любой ситуации и в любой момент времени и на своих ошибках, и на чужих.
А, вы про это. Ну да, так логика не меняется, но читаемость падает.
Вам не кажется, что $something и true чем-то отличаются? Если мне не нужно возвращать $something, а я хочу именно true, то что?

Вы правы, чем-то отличаются. Если вы хотите именно true, то правильный вариант на мой взгляд уже написал PQR

return (bool)$something;


Народ, вы либо устали, либо серьёзно считаете, что писать else после return это нормально? Какой смысл ставить else, если return возвращает результат и код дальше не исполняется?


Согласен с Вами, но я бы код все-таки написал так:

1. Если надо вернуть boolean:

...
return (bool)$something;


2. Если надо вернуть некоторый результат:

...
if ($something) {
    return $newValue;
}

return $defaultValue;
Вот, наконец-то. Под цифрой 2 — то, что нужно, единственное — скобки бы фигурные убрал, вот пунктик у меня =)
Батенька, да вам не на пхп писать надо, а на Brainfuck
Да это вам, дружок, нужно слезть с говноучебников типа «Котеров — PHP 5 в подлиннике»
Не очень хорошее решение ИМХО. Склоняюсь к тому, что все-таки неявный else таки запутывает.
ну человека, который не знает что делает return и при написании каждого оператора / функции лезет в php.net за справкой — естественно запутывает
Сашенька, я свою первую программу написал когда не то, что пхп не было — твои родители еще тебя не зачали даже. И именно потому что я обучил не один десяток таких пионеров как ты я и утверждаю, что писать нужно читабельно даже то, что и так очевидно.
Ну-ну, я вот сейчас в университете учусь, так нам каждый семестр преподают программирование разные доценты (по их словам, супер крутые программисты, подготовившие кучу Стивов Джобсов, Полов Аленнов, Марков Цукербергов и т.д.). На деле же эти люди пишут такую, прошу прощения, херню, что хочется вскрыться и прыгнуть в окно. За три года обучения программированию в университете, я не научился ничему новому, ничего из того, чего бы я не смог почитать в мануале или в любой книжке для нубов.
Значит плохой универ. У меня в академии тоже не было толковых преподавателей по компьютерным дисциплинам. Было парочку, у которых было чему поучиться, но только в частностях.
Понятно что пацаны которые вас учат сами учились примерно в мое время, или даже раньше.
В то время языки были менее стройные, и индустрия была другая. Вполне понятно, что ребята застряли в прошлом. Как в технологиях, так и в стилистике. Сам я еще лет пять назад говнокодил так-же само. И стандарты кодинга я для себя принял только три года назад, а формально описал в виде отдельного документа которого стараюсь придерживаться, и придерживать других (в своих командах) — только месяц назад. :) И я о правильном стиле узнал не из книжек — просто дошел до того, что это уже не удобство, а необходимость. Дальше без него невозможно. Ребята которые преподают в вузах — очень часто оторваны от реальной работы, так что вполне вероятно, что многие вещи просто не почувствовали на своей шкуре… В свое время была такая пословица — «человек в детстве изучавший бейсик, потерян для программирования навсегда». И как человек первая программа которого (да, в 1989 году) была написана на бейсике готов с этой мыслью согласится. Не то, чтобы совсем потерян, но мозг все равно сначала придумывает кривые решения, а уже потом приходится их пееводить на нормальные.

Хотя вполне возможно, что проблема не в них, а в вас. Когда я был уже «опытным программистом» — уже лет семь какого-никакого опыта имел за спиной, я пришел к маме на работу, и познакомился с их системным программистом. Дядька был шикарный. Старый еврейчик, бывший преподаватель, и я бы сказал что он преподаватель от Бога, и ему надо было продолжать преподавать, а не писать… Так вот, когда мы с ним познакомились, я к нему пристал с кучей «умных» вопросов, об особенностях работы тех или иных режимов тех или иных процессоров и т.п. (да, в то время каждый доморощеный говнокодер вынужден был хоть что-то писать на ассемблере, иначе далеко не полетишь). В ответ на что дядька посадил меня рисовать блоксхему решения квадратного уравнения. Я про себя жутко ругался…
Потом до меня начало немного доходить. Скажу, что этот дядька не дал мне никаких практических знаний. Но в программировании это был мой единственный Учитель, которого я могу назвать именно с большой буквы.
мозг все равно сначала придумывает кривые решения, а уже потом приходится их пееводить на нормальные.

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


Ээээ, не одобряю с оглядкой на Линуса ))
«Не то, что входит в уста, оскверняет человека, а то, что из них исходит» ©

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

Вы чуть-чуть вырвали из контекста:
В свое время была такая пословица — «человек в детстве изучавший бейсик, потерян для программирования навсегда». И как человек первая программа которого (да, в 1989 году) была написана на бейсике готов с этой мыслью согласится. Не то, чтобы совсем потерян, но мозг все равно сначала придумывает кривые решения, а уже потом приходится их пееводить на нормальные.
Ммм, возможно я всё-таки контекст не понимаю или не знаю. Но от вышеприведённой максимы веет фатализмом, с которым не готов смириться мой непокорный дух )) Как человек начавший изучение программирования с «Бейсика для детей», упивавшегося чтением справочника по десятку диалектов этого бейсика, выискивавший книги по программированию в местной библиотеке и ненароком ознакомившийся с такими языками как фортран, фокал и после этого (спустя пару лет) впервые дорвавшийся до живого Спектрума и открывший для себя волшебный мир ассемблера… А потом да, было ещё немало интересных языков, но собственно, о чём я — конечно, бывает, что слёту не решишь сложную задачу самым оптимальным способом, но фатализм бейсика? Не верю. Я программирую на русском языке, а потом — уже перевожу в язык понятный машине. Хотя, возможно, я просто чего-то не замечаю и не с чем сравнить? :-)
В принципе, я так понимаю, мы почти из одного поколения и наш путь складывался похожим образом. В каждой шутке, есть доля истины и с этим наверно спорить не стоит, но не хочется абсолютизировать выводы )
Я — за единственный return в методе/функции!

$result = $defaultValue;

if ($something) {
$result = $newValue;
}

return $result;
Нет, я Вас правильно понял — я имел в виду, что попытаюсь человеку аргументировать ))
Как обстоят дела со стабильностью?
Sign up to leave a comment.

Articles