Pull to refresh

Comments 156

Соглашусь, отличное руководство по тому как не надо писать на php.
Руководство «Как сломать мозг тому, кто придет после тебя» :)
Надо. Если есть чувство меры и понимание того, что пишешь — очень мощный инструмент. А код «из одной строчки сделаем миллион» зачастую просто раздражает.
Непонятно для кого статья, да и советы тут приведены исключительно вредные!
for($res = mysql_query(“SELECT …”); $res&&($v = mysql_fetch_assoc($res));)
{
// тут какие-то действия с массивом.
}
Не делайте так никогда, мало того что это менее наглядно, так еще и добавит трудности в отладке.
Эх, и с моим голосом карма не дотянула.
Полезная статья для новичков в php, таких как я.
иди учебники читай, школие.
это все разжевывается в любой книжке.
«это все разжевывается в любой книжке»

Да вы что? O_o Читал две любые книжки — ничего не увидел подобного.
приоритеты операторов вполне описываются в документации
всё остальное содержание статьи — пляски вокруг этой главы
Использование логических операторов вместо конструкций if — это ужасная практика.

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

А для понимания того что такой код лучше не использовать для новичка лучше сказать, что помимо того что такой код дает визуальной читаемости, он еще и не дает производительности… и все равно строка:

$a = ($a == 1)? 5: 9; // со всеми остальными происходит тоже самое, включая switch-case-case…

Интерпретатором будет преобразована в

if ($a == 1)
{
$a = 5;
}
else
{
$a = 9;
}
во блин, дайте редактировать комментарии :(

что помимо того что такой код НЕ дает визуальной читаемости
есть подозрения, что интерпретатор всё таки преобразует в опкод, который для двух приведённых листингов кода, имхо, будет отличаться
Плох тот программист, который не сможет разобраться в собственном коде.
Абсолютно с вами согласен. Но одно дело не знать что так можно делать, а другое — знать но не делать, потому что это не удобно. Поэтому я и написал, что я НЕ предлагаю это использовать.
охренеть… я знаю, что коннекта к БД достаточно в начале скрипта, совершенно не нужно писать mysql_connect перед каждым вызовом mysql_query, мне теперь написать статью про то что коннект можно открывать перед каждым запросом, а потом сказатиь что так делать плохо??
Ну, для начала это только пример. А вообще код приведенный в примере как раз и делает этот самый коннект в начале скрипта, раз уж на то пошло. Никаких утверждений о том, что он делается перед каждым запросом я не писал.
Абсолютно согласен. Стоимость каждой строки кода складывается из стоимости ее написания, стоимости ее тестирования и стоимости ее поддержки. Применение логических операторов в таком виде — довольно сильно увеличивает суммарную стоимость.
Почему «вместо»? Кто мешает совмещать?

Давайте устроим голосование: кто с первого раза не поймёт что делает выражение?
mysql_connect(...) or die;
в нормальных проектах не пишут «mysql_connect(...) or die» =)
и, все равно, такая строка заставляет задумать, пусть даже на пару секунд, в отличие от if(!.. )
Почему? Как раз с точки зрения нормального языка она понятнее: «Соединяйся или сдохни!»
UFO landed and left these words here
Нормальные это какие? По ГОСТу? )
нет, по поддерживаемости и архитектуре. в таком проекте у вас будет:
1. обертка над бд — для удобства или поддержки разных бд. это или просто инкапсулирующий класс, или orm. поэтому код подключения будет выглядеть несколько по-другому.
2. приложение не должно просто, как удачно пошутил Yeah, «сдохнуть» ) в идеале нужно вывести юзеру нормально оформленное сообщение и нормально завершить работу. для этого придется использовать например эксепшены. в достаточно сложной системе мы не можем просто выйти посреди кода.
строки с эксепшенами (да и в этом случае без них тоже) длинны в коде, и в эклипсе это неудобно, поэтому лучше переносить. и «or» тут теряет смысл и понижает читабельность
UFO landed and left these words here
Ну если выражение совсем небольшое и не хочется нарушать структуру кода лишним if'ом, то тернарый оператор имеет право на жизнь.
О того что в коде будет строчка с тернарным оператором читаемость не уменьшится. Хотя если конечно код не будет читать новичек, который просто не знает его синтаксиса.
А вложенные конструкции с тернарным оператором просто взрывают мозг, их конечно юзать не стоит.
> Никогда не понимал желания некторых программистов упаковать побольше комманд в одну строку кода.
Это Вы видимо с Ruby не знакомы :))
Ну почему же?
mysql_connect() or die; вполне имеет право на жизнь.
Тут смысл не в том, чтобы упаковать побольше комманд в одну строку. А в том, чтобы уменьшить количество кода, но и не потерять в читаемости.

Я пишу на Perl, и поэтому примеры будут соотвествующие ))

принимаем параметры
my $param = shift || 0;
Параметр по умолчанию, никаких проверок.

Вместо if (!$a) {$a = $default_value}; гораздо приятнее написать $a = $default_value unless $a; или еще проще $a ||= $default_value;

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

В вашем коментарии есть рациональное звено. Только предствьте — стандарт написания кода, который некому непонятен кроме вас. :-) Идеально для коммерческих скриптов.
Пост ни о чем

Автор, предлагаю название следующей статьи: «Использование константы true в PHP».
О чём. Правда, описанные конструкции мало где можно использовать. Всё равно автору — спасибо.
Я бы сказал, что статья — отличный пример конструкций, которые не стоит использовать в php (и не только). Если вы намеренно хотите «попонтоваться» сложностью кода, то чего уж мелочиться — сразу берите Brainfuck и пишите на нём.

А в реальных проектах такое использовать стоит только тогда, когда от этого код становится понятнее.
Отличная статья!

Может и малоупотребимо на практике, но ведь безумно красиво. Мне как-то даже в голову не прходило, что так можно:
$a? func1(): func2();

«Растягивание» for очень понравилось.

Это — вообще шедевр:
mysql_connect(…) or die()

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

И да, относится это не только к PHP, а к любому C-подобному языку.
вам шашечки или ехать? а если на этой машине ехать не только вам, но и водителям без понимания прекрасного?
Красивый код ради красивого кода глуп и не имеет смысл, хотя достоинства статьи это не умалят, просто не стоит принимать как руководство к действию
IMHO, разбирать просто написанный код, лежащий в 10 разных поддиректориях и в 50 разных файлах (типично «водительский» код — за примером, причем не из самых страшных далеко ходить не надо — PEAR. Чтобы не посыпались обвинения, поясняю — у AltLinux с выходом новых версий может иногда сложиться отличная сиутация, когда версия PHP не совпадает с версиями PHP-шных примочек, и в этом случае — например какая-нибудь функция работает не совсем так, как того ожидалось — приходится оперативно использовать руки и мозги) не в пример сложнее, чем такой сокращенный, если конечно этот сокращенный код будет снабжен комментариями. Без комментариев, возможно, будет несколько напряжнее — с непривычки.
я про это и не говорил, все что имел в виду — подобные конструкции не могут служить признаком профессионализма программиста, ибо как сказал в прошлом великий человек «если физик-ядерщик не может объяснить пятилетнему ребенку чем он занимается — значит он шарлатан».
Я же всегда воспринимаю идущих позади как пятилетних детей и идущих впереди как физиков-ядерщиков.
Потому и стараюсь писать максимально понятно для будущих поколений (не впадая в крайности) и дабы не прослыть шарлатаном
Знаете, если уж на то пошло использование MVC, паттернов програмирования, замыканий, ветвлений и прочей новомодных фишек — точно такой же выпендреж и точно так же не будет сразу понятен програмисту, который этого раньше никогда не видел. Однако что-то я еще ни разу не встречал, чтоб про те же замыкания писали — «ооо, это нечитаемый код», хотя как они работают на первый взгляд понять тоже очень трудно.

Я согласен с тем, что непривычно — это неудобно. Но я не согласен с тем, что непривычно — это плохо.
Это — вообще шедевр:
mysql_connect(…) or die()

А нечитабельно, потому что непривычно.

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

Вот такая конструкция многим не нравится (из-за отрицания):
if(!something)
    return(false);


и приходится заменять на уродливое
if(something==false)
      return(false);


Тут вполне можно поэкспериментировать:

DoIt() || return(false);

SomeFunctionCall(long parameters list, long parameters list)
    || return(false);

(some long condition some long condition some long condition)
    || return(false);


Я таких конструкций в С не встречал ни разу. Да и в РНР это, видимо, не общепринято и непривычно, несмотря на присутствие в туториалах. Иначе б коммент miros выше об отстойности такого не набрал бы +32.
и приходится заменять на уродливое
if(something==false)
      return(false);


честно говоря, мне
if (!something) {
  return(false);
}

куда как понятнее.

Я таких конструкций в С не встречал ни разу.

Неудивительно — они не компилируются:




[weirdan@dev playground]$ cat q.c
int main(int argc, char** argv) {
        0 || return(2);
}
[weirdan@dev playground]$ gcc q.c
q.c: In function ‘main’:
q.c:2: error: expected expression before ‘return’
э-э-э упс, да, лажа. Вместо return читать какую-нибудь функцию. exit(). С return() так хорошо было…
exit() тоже не подходит, она void exit(). Ужас. Туплю.
Позволю себе заметить, что весь изюм скриптовых языков программирования призван ускорить написание кода. Зачем на Perl или РНР писать в Си стиле? Зачем тогда вообще эти языки?
Я и не предлагал использовать или не использовать в РНР то, что написал, т.к. не знаю языка. Это был пример того, как я хотел использовать это в Си (если б с return получилось).

Я понимаю, что блог РНР, но статья применима к любому С-подобному языку. Почему автор заостряет внимание именно на РНР, не понятно.
Имхо конструкция mysql_connect() or die() как раз более читабельна.
этот шедевр уже много лет присутствует в примерах к официальной документации ru.php.net/manual/ru/function.mysql-connect.php

имхо сначала надо научится писать промышленно применяемый код понятно и функционально, а потом начинать сыпать такой вот перчик в очмалых дозах
Вместо
$res = mysql_connect(…);
if ($res) die();
надо
$res = mysql_connect(…);
if (!$res) die();

Тогда оно будет аналогично:
$res = mysql_connect(…) or die();
А вообще пост интересный.
Да, вы правы. Я поправил эту ошибку.
ну для говн… ой простите, лапшекодеров это ещё актуальная тема, но в нормальной то жизни (пусть пока далеко не всегда реальной) должно же быть что-то вроде:
try
{
DB:: connect();

}
catch (Exceprtion $e)
{
LOG:: exception('connect-to-db', $e);
SYS:: terminate();
}

Это я к тому, что отпадут как-то вопросы написания в одну строку или с условием :)
Вот это как раз более смахивает на выпендреж.

Я не согласен с вами. Каждый пишет так, как он считает нужным. Утверждение что человек пишет плохо, только потому, что он пишет не так как вы на мой взгляд и является первым признаком «лапшекодера».

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

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

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

Просто если в коде повсеместно встречается die() — это, обычно, очень плохой признак… отлаживать такой код очень «весело».
«Стандартов» на написание кода не существует. Существуют только рекомендации. Стандарт только один — если код выполняется без Parse Error — то это код по стандарту.

Если die() такая страшная функция, зачем её вообще ввели в язык? Очень просто — die() выполняет очень частую операцию — вывод ошибки с последующим выходом. Её сделали для удобства.

А очень плохой признак это на мой взгляд потому, что данное часто приводится в тутриалах php. И если человек пишет так, это означает что он либо взял код из туториала, либо просто недавно его читал. Правильно, ни то не другое не является показалетем профессионализма. Но сама функция die() вовсе не виновата в этом.

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

Аргумент. А зачем ввели GLOBAL, тоже наверное для удобства… а есть ещё register_globals, magic_quotes, всё тоже вводилось для удобства… А вы хорошо знаете историю развития php?

>«Стандартов» на написание кода не существует.

Общепринятых — разумеется, вы вообще против стандартизации? Ну ваше дело.
Только вот у меня в коллективе — существуют и всем нормальным людям от этого проще.
А чем GLOBAL вам так не угодил? register_globals, magic_quotes — да, это себя изжило. Насколько я знаю, это уберут в PHP6.

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

Я не против стандартов. Я против их неразумного применения. Придумать что-то новое и более хорошее чем старое, можно только полностью отказавшись от старого. А «стандарт» способствует в некотором смысле применению старых практик. Если бы все всегда придерживались стандартов — не было никаких MVC, ROR, AJAX и др. подобных. Ведь кто-то когда-то же их придумал, именно отказавшись от стандартов.

Почему вы так боитесь альтернативных точек зрения?
>А чем GLOBAL вам так не угодил

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

>Вы говорите о том, что так плохо, потому что это не соответствует стандартам вашей организации?

Что-то вы передёргиваете, неприятно. Только что говорили, что стандартов вовсе не существует… и не говорил я, что у меня в организации лучшие стандарты, просто они есть, а у вас в голове их нет.

>Почему вы так боитесь альтернативных точек зрения?
Кто вам сказал, что я их боюсь? Мы тут вроде собрались обсуждать мысли друг друга. Вполне естественно, что я критикую то, что мне не нравится, причём стараюсь аргументировать свои слова

>Я не против стандартов. Я против их неразумного применения.
Эти же слова я написал несколько месяцев назад, про w3c :) почти один в один.
Только вы, упоминая die и прочее, что-то не выглядите человеком, который смог бы «отказаться от старого»
Обожемой! Откуда вы знаете, что в моей голове??? :-)

> Только вы, упоминая die и прочее, что-то не выглядите человеком,
> который смог бы «отказаться от старого»

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

И еще раз повотрюсь. Это был только пример. Конечно, для реального проекта я бы никогда так не сделал. Я вам больше скажу — там mysql_connect. Хотя правильнее было бы mysql_pconnect.

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

Стандарт описывает индентацию, case-конвенцию, комментарии, namespace-ы, названия классов, допустимые сторонние библиотеки (stl, boost, etc.), глобальные и статические переменные, и многое другое.

Соблюдение этих стандартов улучшает читабильность кода, уменьшает количество ошибок и ускоряет интеграцию новых членов команды.
>Стандарт только один — если код выполняется без Parse Error — то это код по стандарту
с таким подходом и получаются продукты типа ms ie
Вы видели код ms ie и его кодинг-стандарты? Покажите нам тоже.
ну это я конечно ляпнул, да. код ie я не видел и как-то не горю желанием, ыы
но все равно, такого рода подход ведет к запутыванию кода, что потом аукается на качестве
Ничё, первый блин всегда комом. :-)
А мне лично статья понравилась, насчет бедных начинающих разработчиков, которые обязательно ломанутся… — у каждого своя голова на плечах, что-ж теперь, вообще ничего не писать? Найдут куда ломануться и так :)
Интересно, что многие вещи пришли ещё из Си. В частности, штука с || и && будет работать и там тоже.

Си, как и PHP, язык с нестрогой типизацией, поэтому там и func1() + func2() будет работать. Правда, что интересно, стандарт не оговаривает порядка вычисления операндов, поэтому нельзя заранее сказать, что будет вызвано раньше: func1 или func2, то есть разработчики компиляторов сами этот вопрос решают.
Вообще-то у каждого оператора присутствует такая вещь как ассоциативность. Она и определяет порядок вычислений. Асоциативность может быть правой или левой. У оператора «+» левая ассоциативность, т.е. выражения func1() + func2() будет вычислено слева на право. Т.е. сначала func1() а потом func2(). Подробнее об этом можно посмотреть www.php.net/manual/ru/language.operators.php

Алгоритмы вычисления выражений насколько я знаю един для C-подобных языков. Поэтому даже в Си func1() + func2() будет выполнятся точно так же.
Но, обратите внимание, сколько плюсов уже получил комментарий уважаемого enartemy. Как приятно видеть на IT-ресурсе много образованных и внимательных айтишников, Вы не представляете. :)
Ассоциативность оператора и порядок вычисления операндов — это разные вещи.
Правая ассоциативность оператора плюс говорит о том, что a + b + c вычисляется в порядке (a + b) + c.

Порядок вычисления операндов a, b и c может быть при этом произвольным. Именно поэтому в Си и Си++ не рекомендуется использовать конструкции вида foo[i] + foo[i++]. Один компилятор может сначала вычислить значение foo[i++], при этом i увеличиться, и только затем он будет вычислять foo[i]. Другой компилятор может сделать по другому.

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

И у плюса все-таки левая ассоциативность.
Из заголовка не понял, каких выражений-то :)
Сразу подумалось про маты в комментариях.
я не могу точно сказать в каких языках такая возможность есть, но
у пхп есть минус, которого нет в языках TIMTOWTDI:
нельзя сразу обратиться к элементу массива, который вернет функция
arElement = myfn()[ 'el1' ];
а выглядит эта конструкция как простое выражение…
Да, меня это всегда бесило… Не люблю временные переменные.
А я вот не вижу ничего хорошего в такой возможности

$arElement1 = myfn()[ 'el1' ];
$arElement2 = myfn()[ 'el2' ];
$arElement3 = myfn()[ 'el3' ];

это же ужасно выглядит, не говоря уже о том что либо функция будет вызываться 3 раза, либо php самому придётся заменить этот код на подобное выражение:

$arElements = myfn();
$arElement1 = $arElements[ 'el1' ];
$arElement2 = $arElements[ 'el2' ];
$arElement3 = $arElements[ 'el3' ];
Вот тут вы не правы. Довольно часто бывают ситуации, когда функция возвращает массив, из которого нужно выдернуть только одно значение, причем только один раз.

Обычно:
$tmp = mysql_fetch_array($result);
$id = $tmp[0];


А можно было бы так:
$id = mysql_fetch_array($result)[0];


(Естественно, перед этим проверка if ($result)… и if (mysql_num_rows($result) != 0) ...)
Сразу же на ум сразу же пришла подобная ситуация (:
Тьфу блин, случайно ctrl+enter нажал :) С im-мэссенджарами случайно попутал :) Может:
list($id) = mysql_fetch_row($result);
подойдет? :)
гы, кстати для таких ситуаций это отличный способ
Для таких — подойдет, для ассоциативных массивов — не подойдет.
для ассоциативных подойдёт

function getSomeArray() {
return array(«A»=>«B»,«C»=>«D»);
}

$x = current(getSomeArray());
тоесть писать можно будет так:

if ($result && mysql_num_rows($result) != 0) {
    $id = mysql_fetch_array($result)[0];
}

вместо:

if ($result && $row = mysql_fetch_array($result)) {
    $id = $row[0];
}

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

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

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

Категоричность… вы считаете себя хорошим программистом?
Он считает себя хорошим категористом (:

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

Автор — молодец, предоставил многим материал для «размышления».

Сам я довольно часто вместо if'ов в JavaScript'e использую: a = a || 'defaultValue'; или! a && (a = 'defaultValue'); (последнюю конструкцию и в PHP юзаю) — это намного удобней, быстрей, и ни разу я не слышал от коллег, что это неудобочитаемо. И называть это «выпендрежем» — по меньшей мере голословно. При таком отрицающем подходе тогда, действительно, — незачем MVC, Pattern'ы проектирования, ООП в целом и т.д. Это все равно, что говорить (в JavaScript): var a = new Array(); — правильно, а var a = []; — уже выпендреж. Бред. =) Аналогию можно провести — есть математика уровня техникума, есть уровня университета. Так с какой стати мне писать на уровне математики 7 класса школы, чтобы код был понят каждым новичком после прочтения книги «PHP для чайников»?
ах да, при этом я, естественно, не отрицаю if'ы, сокращенные конструкции я использую лишь для одиночных условий (дальше, уже, действительно, может начаться каша — поэтому — все в меру надо!)
А где же умные слова как «тернарный оператор» и «левоопределенные выражения»?
Зачем? Это что, увеличит читаемость текста или произвдет на кого-то впечатление?
Не думаю.
Ну тогда давайте описывать код словами типа «вот эта закорючка», это всем понятно.
Я что-то не помню, что бы писал выражение «вот эта закорючка».
Статью лучше было назвать «использование неприличных выражений в PHP».
Все же читаемость кода важна, если это не пример из десяти строк со сроком жизни 10 минут.
Согласен,

enartemy, а ещё мне было бы интересно послушать ваше мнение о регулярных выражениях в php :), нет правда, я без сарказма, именно ваше.
В регулярных выражениях нет такого полета как здесь. Там чистое подобие «Brainfuck» (сравнение на мой взгляд вполне уместно). Там не стоит вопрос о том, как сделать так, чтоб было еще короче или еще красивее. Работает — и слава богу. Притом, обычно частота использования регулярных выражений очень не высока. Так что говорить об оптимизации или еще чего-то такого нет смысла, так как потратишь уйму времени и сил и в итоге получишь экономию на спичках. Игра не стоит свечь. Такое мое мнение.
>mysql_connect(…) and mysql_select_db (…) and mysql_query(«SET NAMES utf8») or die(mysql_error());

>$res = mysql_connect(…);
>if (!$res) die();

Одному мне не привычно использовать такие конструкции?

По первому случаю:
Во многих компиляторах нельзя заранее сказать, в какой последовательности будут вызваны функции. Слева направо, справа налево или вперемешку. В php — гарантировано?

По второму:
Мне проще сравнить $res с false, чем потом долго искать ошибку (а такие сравнения в чужом коде сплошь и рядом).
В php — гарантировано?

Гарантировано, интерпритатор-то один :) А компиляторов вообще нет.
&& и || — операции короткого замыкания, это записано в стандарте (в C, C++, Java). В Perl тоже короткое замыкание. Да и вообще во всех традиционных императивных языках.

www.php.net/manual/en/language.operators.logical.php

(Хоть бы сами документацию по PHP посмотрели, неужели это так сложно?)
А почему никто не пишет, что во избежание артефактов нужно сравнивать с учетом типов в php, а именно
if ($a === $some_value)
{
//bla-bla
}

or

if ($a !== $some_value)
{
//bla-bla
}

кстати, конструкция switch в php использует для case-ов нетипизированное сравнение (==), поэтому я стараюсь избегать switch в php скриптах

т.е. данный код

$a = true;

switch ($a) {
case 1:
echo «1»;
break;
default:
echo «default»;
break;
}

выведет — «1»
При чтении всех комментариев о неудобочитаемости подобных выражений возникла мысль о параллели с использованием идиом в текстах на естественных языках.

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

Перенося изложенное в область языков программирования IMHO можно сказать, что использование идиом вполне допустимо при соблюдении любого из следующих условий:
  • • идиома является достаточно известной в культурной среде данного языка (var foo = foo || 'baz' в Javascript, mysql_query(«...») or die(mysql_error()); в PHP) и предполагается читатель, знакомый в достаточной мере с языком для того, чтобы понимать ее значение;
  • • идиома документирована (либо уже задокументирована где-то, либо к проекту прилагается краткий словарь идиом с толкованием);
  • • идиома идентична (либо достаточно схожа с) идиомам(и), используемыми в других языках и предполагается знакомство читателя с этими языками (в качестве примера можно привести использование битовой арифметики для операций с набором флагов, сохранённых в одном интовом значении: if (error_reporting() & E_NOTICE) doSomething();. Такой код будет понятен любому, кто владеет C/C++/PHP/etc. В естественных языках же можно встретить примеры идиом, переводимых напрямую: «простите мой французский» — «pardon my French»

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

Наткнулся, как мне кажется на баг, ну или как минимум особенность PHP, связанную с конкатенацией строк.

1. $a = $a. $b;
2. $a .= $b;

Первый вариант выполнятеся в сотни раз дольше.

Строка $b должна быть не менее 40 символов, чтобы заметить результат. Количество итераций — порядка 10000.

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

Вот кусок кода, которые каждый может проверить у себя сам:

<? php

$a = NULL;
$b = «Довольно длинная строка, символов эдак 40»;
$start = getmicrotime();

for($i=0;$i<10000;$i++) {
$a = $a. $b;
}

$end = getmicrotime();
$time = $end — $start;
echo $time.«
»;

$a = NULL;
$b = «Довольно длинная строка, символов эдак 40»;
$start = getmicrotime();

for($i=0;$i<10000;$i++) {
$a .= $b;
}

$end = getmicrotime();
$time = $end — $start;
echo $time;

function getmicrotime()
{
list($usec, $sec) = explode(« „, microtime());
return ((float)$usec + (float)$sec);
}
?>

Пожалуйста, опубликуйте это в соответствующем разделе. Может быть гуру PHP давно знают, как быстрее и правильнее делать простейшие операции, а вот новичкам будет точно интересно.
Как минимум, вы не указали на какой версии PHP вы наблюдаете подобное замедление.
1. $a = $a. $b;
2. $a .= $b;

> Первый вариант выполнятеся в сотни раз дольше.

Естественно (говорю даже не запуская). Смотрите:

1. Происходит вычисление правой части, в результате создаётся новая строка в памяти, и $a присваивается эта строка (в результате чего предыдущее значение внутри $a выбрасывается). Итого: одно выделение памяти, одно освобождение, два копирования.

2. Происходит добавление к уже существующей строке, присваивания нет, происходит по сути просто увеличение буфера, и максимум одно копирование.
ну и как бы bugs.php.net/bug.php? id=44069
блин. bugs.php.net/bug.php? id=44069
исправлен в 5.2.6
в php действительно варианты 1 и 2 реализуются по-разному?
Доберусь до рабочей машины — смогу сказать. Впрочем, вы можете и сами посмотреть (для этого пригодится Vulcan Logic Disassembler)
я не php-программист, поэтому этот грозный, судя по названию, инструмент для меня бесполезен.
Интересуюсь потому, что искренне удивило.
результаты такие:
для случая $a = $a. $b:
   4     4  EXT_STMT
         5  CONCAT                                           ~2      !0, !1
         6  ASSIGN                                                   !0, ~2

Здесь видно, что результат CONCAT записывается во временную переменную (~2) и затем присваивается.

для случая $a .= $b;
   4     4  EXT_STMT
         5  ASSIGN_CONCAT                                            !0, !1

Здесь конкатенация происходит без использования временной переменной.

спасибо!

мы тут ещё в одной ветке пообщались и один товарищ определил, что и в c++ есть разница в этих операторах, а я сделал предположение почему (в с++ я тоже глубоко не разбираюсь, так только когда-то алгоритмы писал).
habrahabr.ru/blogs/php/38754/
честно, похоже на индусский код, который хрен прочтешь.
Я просто не понимаю, кто и за что минусует, вы видели этот код?? Это все, всадники апокалипсиса спустились на землю, чтобы вершить страшный суд. Так писать НЕЛЬЗЯ!!!
Есть мысль, что минусуют за преобладание эмоций над аргументацией.
Имхо, вообще не стоит навязывать именно какой-то стиль программирования, у каждого он свой. Темпаче в каждой отдельно взятой компании есть внутренние правила написания кода. Что ближе — то и пишете, со временем каждый эволюционирует и придёт к своей истине :)
Ну вот если я напишу вот так (JS):

var a = b || 'Foo'; // in-place fromMaybe, опять монады, хе-хе

то это гораздо более читаемо чем:

var a;
if (b) { a = b; }
else { a = 'Foo'; }

(и прочие подобные варианты)

Экономьте свои keystroke'и, ваши пальцы вам еще пригодятся. :)

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

PS вы не видели =,
Да просто надо забанить за пропаганду такого бредового стиля!
Даешь чистый и понятный код!
Все, кто любит всякие заморочки в синтаксисе, пишут на перле.
А ещё можно так:
mysql_connect().mysql_select_db().mysql_query() or die();
Только дурь это.
А вот как раз так лучше не делать. Хотя бы потому что сначала результат будет перевен в строку оперетором «.», а потом в boolean при выполнении «or». Более того, это явно направлено на снижение читаемости. В моем примере можно прочиать «сделать коннект и выбрать базу и выполнить запрос или вывести ошибку». А в вашем примере — действительно — дурь.
я знаю :) я вообще не люблю подобные изыски. особенно в случае с бд — люблю, знаете ли, всегда явно указывать идентификатор соединения, чтобы не дай бог не выбрать что-нибудь из соседней базы :)
наврядли я буду это использовать, но за просвещение спасибо.
Попытки писать в псевдофункциональном стиле на PHP.
Ужаснее подхода не встречал. Не в ту сторону развиваете свои профессиональные навыки, автор!
Очередная голословность :), не подкрепленная ничем, кроме личных (не)привычек.
Мне кажется, что доказывать необходимость простоты чтения кода не имеет смысла, если вы, конечно, работали над серьезным проектом в команде больше, чем один человек:)
> простоты чтения кода

недоказуемый субъективизм (локальная привычка к синтаксису). Повторю, никто не отрицает if'ы — я как раз за них (в случае, если условий больше одного). Однако, a = a || true; — прозрачно, чисто и красиво (кстати, я прекрасно осознаю, что и мое утверждение — тоже локальный субъективизм, но я в отличии от Вас не позволяю себя навязывающе утверждать)

> не имеет смысла

на нет — и суда нет, только в таком случае к фразам типа «Ужаснее подхода не встречал.» добавляйте магическое слово «ИМХО» — тем самым Ваше мнение не будет утверждающим, а лишь предполагающим.
бессмысленный разговор. Терпеть не могу эти 4 буквы, которые вы мне навязываете к применению. Тема закрыта.
А по-моему наоборот всем срочно нужно переходить на такой подход :) сколько дискуссий по поводу того что в PHP низкий порог вхождения и потому к нему отношение как к недоязыку… Дык вот! Прекрасная возможность все исправить, обойдем по зломогучести перл и будем впереди планеты всей! :)
На РНР по зломогучести перл не обойдешь )))
Вы уверены? :-)))) Обойдешь-обойдешь… Еще как обойдешь.
Уверен ;)
tochkak.ru/job/ попробуйте разобраться, что оно тут делает ))))
Не очень впечетлило. На перле и покруче можно написать. Я как-то видел код програмы на перле (я не найду её сечас уже, которая на вид представляла собой набор символов. Натуральный брейнфак.
not exp log srand xor s qq qx xor
s m m length uc ord and print chr
ord for qw q s our use tr hex q m
xor eval xor print qq q q xor int
eval lc q m cos and print chr ord
for m xor scalar ord sin print qq
qq xor int eval lc qq y split cos
and print chr ord for qw x printf
each return local x y and do exit

Фигня это все.
Код приведенный по ссылке разбирает POST запрос. Работает в экстремальном окружении. Стабилен. И очень быстр, во много раз быстрее CGI.pm и при этом раз в сто короче ;)
Поправьте, пожалуйста.
— Почти все, что вы пишe те в PHP
Тогда и в русскоязычную документацию по php надо отправить… Цитата-то оттуда.
Не издевайтесь. Где я, а где русскоязычная документация на PHP. (Я её даже как-то и не читала, признаться, всё время англоязычной пользуюсь). Что на глаза попалось, то поправила. ;)
Я сам часто использую описанные автором решения. В меру это действительно, помогает упростить разработку. Начинающим не помешает знать о таких решениях.
а я считаю, что статья крайне полезная, нужно знать как это делается и уметь читать, не вижу что б автор заставлял вас использовать эти методы, не хотите не используйте, но знать о их существовании вы обязанны если хотите считать себя хорошим хотябы кодером.

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

$res = mysql_connect(…);
if (!$res) die();

Аналогично:

$res = mysql_connect(…) or die();

выбор как и что использовать, конечно, остается на совести программиста
Sign up to leave a comment.

Articles