Pull to refresh

Comments 202

Многие советы банальны, хотя и правильны, а что касается 5.3 — просто немного what's new.
А вот что касается примера с собакой, то для индексов массива рекомендуется использовать array_key_exists(), а не isset().
isset все же быстрее, а array_key_exists лучше использовать для проверки наличия элемента в массиве, в котором могут быть null в значении.
Попробуйте:
$test = «test string»;
if( isset($test[0]) ) unset($test[0]);

(причины 2people.ru/?p=29)

Не стоит учить кодеров делать:
function my_temp_map($x) {
return $x + 1;
}
$result = array_map('my_temp_map', $arr);
Иначе получаются конструкции вида: govnokod.ru/3736
С которым вы получите море нестандартного секса, кода потребуется отрефакторить это месиво.

К тому-же, пример не самый удачный, т.к. вы всегда могли использовать create_function().

create_function — это очень очень плохо, так как PHP-код в таком случае надо записывать строкой, без подсветки синтаксиса, инспекций и тп. Ну и да, я там еще замыкания упомянул.
Я не автор статьи и высказался только насчет isset :)
И я даже не знаю что внезапно заставит меня что-то проверять isset'ом в строке. Не уверен что то, с чем ты работаешь есть массив — проверь.
Работа без выходных видимо сказывается, и получилось так, что я сразу ответил вам и автору статьи.

Конечно вы не будете проверять строку, но допустим, что есть некий Сергей, который не знает про юнит-тесты, дует по нескольку раз в день и не мотивирован деньгами и вот Серёжа решил исправить метод класса, который возвращает массив, после чего, тот стал возвращать строку. После этого вы офигеваете, как может получиться так, что вы проверили существование элемента массива, провалились в if, но там выводится ошибка, что элемента нет.
Так это уже проблемы удутого Сергея, не?
но в результате вы имеете свой нерабочий код, который надо раскопать, а только потом пинать «Сергея».
>>isset все же быстрее

OMFG. У вас 100000 проверок в цикле?
На высокопосещаемых проектах обычно даже такие мелочи могут облегчить жизнь серверу. А учитывая что таких мелочей может быть великое множество — почему бы не стараться писать всегда так, как надо?
Оптимизация одного SQL-запроса стоит миллиона таких микрооптимизаций.

Видел я товарищей, которые сидят и меняют двойные кавычки на одинарные, при SQL-запросах типа order by rand().
О, расскажите, плз, подробнее о товарищах. Зачем они меняют кавычки на order by rand запросах?
Типичный диалог (утрирую, конечно):

— Как ускорить код: mysql_query(«select * from table where category_id=$cat_id order by rand() limit 10»)?
— Заменить кавычки на одинарные!
Имеется ввиду, что в PHP одинарные кавычки обрабатываются быстрее чем двойные, т.к. в одинарных нет специальных эскейпов и вставляемых переменных. :-)
еще есть стандарты кодирования…
ну тогда еще хорошее кеширование стоит многих оптимизаций sql-запросов, вариантов оптимизации всегда много и я нигде, по-моему, не говорил что стоит ограничиваться микрооптимизациями скриптов.
isset лучше тем, что позволяет избавиться от проверки на то, что массив вообще массив.
Если переменная $x содержит по той или иной причине не массив, а скажем null, то isset() вернет false и все будет ок.
array_key_exists() же выдаст notice.
Массив или не массив, а также существует ли он, проверять нужно несколько заранее. А в статье сказано
Часто оператор "@" используется при доступе к ассоциативному массиву в тех случаях, когда нет уверенности в существовании того или иного ключа.
(isset($x)&&is_array($x)&&array_key_exists($y,$x)) — это явно и намного длиннее писать и дольше будет работать, чем (isset($x[$y]))
Если говорить о краткости, то собака ещё короче. Если говорить о скорости работы, то если эта операция делается не в цикле на многие тысячи операций, то высчитывать, что быстрей — экономия на спичках. А если говорить о красоте кода, то инит стоит делать не для каждой переменной персонально с километровыми изсетами, а один раз написав нормальный конструктор, класс, функцию или что там у вас.
ситуации разные бывают :) лично мне привычнее юзать isset()
Десять тысяч спичек уже рубль!
Как выше уже сказали
Оптимизация одного SQL-запроса стоит миллиона таких микрооптимизаций.
как я уже выше ответил, не надо зацикливаться только на самом значительном, надо писать правильно и грамотно всюду.
Если вам требуется экономия на спичках, значит что вы просто неправильно спроектировали приложение, пересмотрите ТЗ, возможно вы что-то сделали не так…
Прекрасно сказано! — habrahabr.ru/blogs/php/102444/?reply_to=3185635#comment_3185240 и прекрасный ответ.
Не хочу вступать в спор. Экономить или не экономить на спичках, каждый решает для себя. Я считаю, что экономить нужно))) Вы что нет. Причем я буду экономить даже при идеальном проектировании проекта.
В результате я затрачу больше времени на написание кода, но при прочих равных сайт при написании которого экономили выдержит на том же сервере на тысячу уникальных посетителей больше… мелочь а приятно.
Пример из жизни:
Переверстывание сайта (ничего серьезного, почистил стили из HTML) уменьшил размер страницы (HTML) всего на 3.5 килобайта (Одна спичка) дало уменьшение дневного трафика на 12,5 Гигабайт тоже мелочь но тоже приятно…
Там спичка, здесь спичка… зависит исключительно от подхода, давайте не будем спорить!
3.5 килобайта при соответствующей посещаемости это не спичка а бревно. Однако и его можно устранить проще (вынести статику, причём можно даже не всю, а можно только пару картинок которые есть на каждой странице, логотип например, на отдельный «школохост», для статики пойдёт даже хостинг за 1$ в месяц, и проблем не будет) и ОПЯТЬ ЖЕ это только в случае если в этом есть необходимость (если канал даже в часы пик не забивается больше чем на 50% то какой смысл оптимизировать ?)

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

Если же посещаемость вышла за границы разумного, а узкие места уже не найти, и хочется оптимизировать уже каждый такт процессора, и каждый байт расхода оперативки, то и вовсе стоит пересмотреть архитектуру. (ну или если возможно переехать на более мощный сервер)
У каждого свой подход и оба имеют право на жизнь… Давай те не будем спорить)))
>то проще оптимизировать «узкое место» а не вылизывать спички

Если вылизывание сразу при кодировании (хрестоматийный пример с одинарными и двойными кавычками) не составляет труда, то почему бы и не вылизывать? Никто же не говорит о том, что если половина посетителей не получают запрошенную страницу, то надо бросать всё и искать где можно поменять двойные кавычки на одинарные.
Есть мнение, что наличие собаки "@" в коде свидетельствует о его говнокодистости (BTW, она используется не только при доступе к ассоциативному массиву)
Да я ж и не против. Спор у меня с камрадами завязался по поводу isset vs array_key_exist.
> что касается 5.3 — просто немного what's new.

Это не просто «немного». Там нововведений больше, чем в предстоящем PHP 6.
Вы еще веритев PHP 6. Кто-то из PHP team недавно признался, что у них серъезные проблемы с одним из главных нововведений 6-ой версии — Юникодом. Поэтому, скорее всего, нас ждет PHP 5.4 в обозримом будущем.
Я перестал верить после того, как при переходе 5.2 -> 5.3 они понапихали туда столько нововведений, что с лихвой хватило бы на переход 5.x -> 6.x :)
В статье немного what's new из 5.3. Конкретно одна фича и ссылка на чейнджлог.
Мда, и сколько вы уже кодите на пыхе?
Советы подобные уже пахнут молью.
Нет, именно молью, которая съела весь нафталин.
E_NOTICE уже входит в E_ALL, не надо дублирования :)
А я думал, что мне глаз режет :)
Не знаю, насчет главного нововведения php 5.3 я-бы поспорил, для того чтобы вернуть из метода параметризованный исполняемый код — в пхп есть классы, и в языке где за основу взята явовская объектная модель — это имхо даже более предпочтительно, ну там типовое решение «команда» и т.п., а так — анонимные функции это конечно приятная плюшка, но так как она сделана в виде нашлепки сбоку, а не является одной из основ языка — то такой пользы, как например в яваскрипте — от нее соответственно нет, ни агрегацию, ни перегрузку методов с помощью нее не сделаешь.
Я лично в версии 5.3 больше всего ценю пространства имен, это хоть вещь и чисто синтетическая, но насколько все-таки аккуратнее и слаженней становится код, гораздо приятнее работать.
Пространства имен вещь такая… спорная. Вернее, вообще нейспейсы — очень полезная штука. Но в PHP реализовали их мягко говоря странно. Более-менее удобно если прямо все засунуть в неймспейсы.
Ну да, конечно, есть некий диссонанс с тем что несмотря на то что свой код можно оформить как пожелаешь — несколько тысяч встроенных функций и классов находятся в глобальном пространстве имен, сторонние фреймворки/библиотеки, те что активно развиваются — переходят на неймспейсы довольно таки быстро, на хабре уже были анонсы и doctrine под неймспейсы, и zend framework, а тяжелое наследие php 3-4 будет еще долго нас преследовать :)
>> Товарищи, которые еще не перешли на utf8! Переходите! Чем раньше тем лучше.

Гм… Нужен ли utf8 для русского проекта с БД на cp1251?

>> Самое главное нововведение этой линейки PHP — это анонимные функции…

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

ЗЫ. Я бы посоветовал книжки читать. Алгоритмы и т.д.
Старые свои проекты, сделанные на cp1251, переделывать на utf8 смысла не вижу, т.к. проекты только для .ru-сегмента.
Для новых же проектов скорее всего выберу utf8.
А есть ли еще какие-то плюсы от utf8, кроме мультиязычности, по сравнению с тем же cp1251?
Облегчение интеграции сторонних программ/библиотек, сейчас уже огромное количество софта из коробки использует utf-8, соот-но для cp1251 нужно будет каждый раз делать конвертацию туда/обратно, конечно в случае когда к программе на utf-8 нужно подключить библиотеку работающую с национальной кодировкой ситуация будет аналогичной, но таких библиотек банально меньше, так как они ограничены регионом, в котором разрабатывались, да и популярность utf-8 в массах нельзя отрицать.
Всяческих спецсимволов в unicode больше, например, если надо вставить в текст формулу, да и просто прикольные есть :)
Аякс, флеш и прочее, прочее, прочее.
так они же в любой кодировке работают.
что-то определенное в них?
xmlhttprequest.ru/#encoding
Если Вы используете только UTF-8 — пропустите эту секцию.

Все идущие на сервер параметры GET/POST, кроме случая multipart/form-data, кодируются в UTF-8. Не в кодировке страницы, а именно в UTF-8. Поэтому, например, в PHP их нужно при необходимости перекодировать функцией iconv.

// ajax.php
$name = iconv('UTF8','CP1251',$_GET['name']);
С другой стороны, ответ с сервера браузер воспринимает именно в той кодировке, которая указана в заголовке ответа Content-Type. Т.е, опять же, в PHP, чтобы браузер воспринял ответ в windows-1251 и нормально отобразил данные на странице в windows-1251, нужно послать заголовок с кодировкой в php-коде, например так:

// ajax.php
header('Content-Type: text/plain; charset=windows-1251');
Или же, такой заголовок должен добавить сервер. Например, в apache автоматически добавляется кодировка опцией:
# в конфиге апача
AddDefaultCharset windows-1251
Во флеше юникод — нативный стандарт.
Столкнулся с тем, что в проекте, который создавался на CP1251 возникла необходимость использовать AJAX и отдавать в JSON, который работает исключительно с utf8. Пришлось все переводить на utf8, потому что в итоге выгоды было больше, чем затраченного времени на переход.
У Вас все еще есть БД в cp1251 о_О
Наверное предполагается, что несколько лет назад проект был сделан в 1251, а сейчас в юникод не переводится по причине того, что никто не оплатил этого перевода.
Это все за utf8 так набросились? Я вроде привел конкретный пример… Впрочем, уже не удивляет.
Честно сказать не знаю как обстоят дела именно сейчас, но в компании в которой я работал раньше, для защиты продуктов использовался сервер лицензий (продукт стучал на сервер и проверялась лицензия), а для защиты механизма проверки и вообще кода, все php файлы кодировались ZendGuard (оффициально купленная версия). Как известно для работы приложения пропущенного через Zenguard на сервер должен быть подключен модуль Zend Optimizer (в нашем случае он должен быть не ниже 3.х.х). И вот собственно проблема: ZendOptimizer не работает с php 5.3.. После обращения в тех поддержку Zend, был получен примерно следующий ответ: «Да мы в курсе данной проблемы и наши высоко квалифицированные специалисты уже решают эту проблему, приносим свои извенения.»

Насколько мне известно, Zend Optimizer и по сей день невозможно подключить к 5.3, если я не прав прошу поправте.
Невозможно. И с ним вообще все плохо — ZO < 3.3.9 конфликтует с PHP >= 5.2.10, а 3.3.9 не существует для FreeBSD 64bit, используемой на многих виртхостингах. Поэтому теперь выбор хостинга для зазенденного проекта превратился в увлекательный квест. А на своей Ubuntu 10.04 именно из-за Зенда пришлось откатить PHP до 5.2.10 (т.к. очень много заказов под HostCMS, которая требует ZO).
Насчёт @ — иногда без него нельзя, к примеру сделайте file_get_contents() на удалённый урл — заглушить warning о 404 или подобной ошибке можно либо отрубив E_WARNING, либо заткнув её через @. display_errors не берём в расчёт, ибо в лог это всё равно попадает и только там мешает, аля false positive.
Запрос на удаленный урл лучше сделать курлом имхо.
Вы не забывайте, что иногда cURL'a может и не быть. Это не модуль, который идёт включённым по умолчанию. И на самом деле то же относится к ошибкам при работе с файловой системой. Проверить файл есть или нет можно, а вот если случится ошибка чтения — опять же всё полезет куда не надо.

А ещё есть create_stream_context, который удобно использовать с file_get_contents()
Вообще ошибки чтения лучше не проглатывать а выводить в логи.
Я для боевого сервера включил все ошибки, включая нотисы, с записью в логи.
Любые ошибки лучше видеть, а не подавлять.
Главное лимиты на логирование поставить, а то может все место съесть.
Если ошибки валятся в логи с такой скоростью, то что-то явно не в порядке.
Как правило, больше всего валится нотисов, а с ними надо бороться :)
Всякое бывает в жизни сервера и сайта.
Логи могут быть общими и для интерпретатора, и для приложения (например 404 туда писать, чтобы сразу было видно, что 404 возникла не из-за левого урла, а из-за ошибке в коде)
ну мне кажется, что лучше все таки разделять.
Для решения этой проблемы в Unix-системах уже десятки лет используется ротация логов (logrotate, newsyslog etc). Не надо изобретать велосипед.
А вот не надо делать file_get_content на удалённый урл. Надо юзать curl.
См. ответ для mephisto выше.
set_error_handler() и там фильтруйте warning/notice
Как только люди готовы извратиться, лишь бы собаку не использовать!
Мне эта ситуация напоминает историю с goto в Си: программистов так долго им пугают в книжках/в вузах/и т.д., что они начинают шарахаться от него аки черт от ладана, даже в случае, когда goto — самый простой и понятный способ достичь требуемого эффекта.
@ в PHP, хардкод «магических чисел» и не только — это дурные привычки, которых надо избегать. Тем более, возможность есть.
//хардкод «магических чисел»— это дурные привычки, которых надо избегать
Не покушайтесь на любимую 0x5f375a86! :)
Да и goto — зло. Писать с ним может быть и проще, но когда открываешь чужой код с goto и начинаешь понимать его логику, то невольно вспоминаешь и книжки и ВУЗы.
Собака работает очень медленно, потому что интерпретато переключает внутри себя режимы обработки ошибок.

Лучше уж еррорхандлер.

А вообще, я бы руки отрывал за собаку, особенно когда такой надо дебажить.
Это не извращение, а конвертация исторически сложившегося дурного механизма обработки ошибок в полноценные исключения. В тех же Python и Ruby почему-то никому не приходит в голову ничего тушить никакими собаками — ошибки такого рода выбрасывают исключения, для обработки которых используются try-catch. В php для этого нужно всего 4 строки кода, так зачем мучаться?
И чем, спрашивается, собака хуже условного try {...} catch(everything) {do nothing}? Наоборот, писать меньше.

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

function err_handler($errno, $errstr, $errfile, $errline )
{
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

function exc_handler($exception)
{
Log::write(«Uncaught exception: ». $exception->getMessage(). "\n";
}

set_error_handler('err_handler');
set_exception_handler('exc_handler');



try {...} catch (...){}
UFO just landed and posted this here
Не всегда есть возможность и/или время сделать правильную обработку. Идиальный мир на то и идиальный, что там делается всё правильно. А иногда сами скрипты настолько небольшие, что fsockopen со всей обработкой будет больше чем сама программа.
Не вижу минусов cp1251, если потребитель трафика русс. сегмент, зато вижу экономию трафика поскольку символы в utf занимают больше места
Экономия незначительна и покрывается сжатием, а вот проблем потенциальных — куча. Я встречал немало библиотек, которые надо было допиливать для cp1251, но без проблем работали в случае с utf8.
незначительна, аха, всего в 2 раза…
как это у вас получилось в два раза?
Не два. Там больше на самом деле.
1. Обработка регулярного выражения, в котором есть класс символов типа \w (буква). В однобайтовой кодировке это один-два такта + допускает параллельное вычисление, в utf-8 несколько десятков оперций сравнения.
2. Таблица преобразования в 1251 – это 256 байт, которые помещаются в кэш современного процессора, а таблица преобразования для utf-8 вообще не существует в виде одной таблицы, это куча таблиц и соотв. условных переходов.

Так что зря человека заминусовали. Он говорит дело и если для него так важны накладные расходы и он не испытывает проблем с AJAX, то всё верно. Для его кириллического сайта cp1251 оптимальна.
Накладные расходы в скорости работы встроенных mb* функций по сравнению с не-mb минимальны, я проверял. А размер избыточности данных в процессе передачи вообще не имеет смысл обсуждать. Регулярки в ответственных местах (которые часто выполняются) вообще не стоит использовать ни с cp1251, ни с utf8.
Мы говорим о микросекундах и я не понимаю в чём вы пытаетесь меня убедить. Вы сами подтверждаете мои слова о разнице в скорсти: 'расходы в скорости работы встроенных mb* функций по сравнению с не-mb минимальны'. Если в том, что на это стоит закрыть глаза и рваться к юникоду, то я спрошу вас- зачем это человеку, у которого весь его функционал работает и с использованием cp1251? Если в том, что расходов нет, то мы кажется выяснили, что они есть. Если в том, что ими стоит пренебречь, то я не вижу спора- тут каждый выбирает сам. Меня лишь поразила твердолобость обсуждавших этот вопрос людей. Для примера:
Записи $a=«Привет, мир» и $a='Привет, мир' имеют разное время выполнения. Разница минимальна. Вы же не станете меня сейчас убеждать в том, что мне стоит использовать первый вариант, потому что с ним проще не ошибиться?
Не пытаюсь я вас убедить в чем-либо. В вашем случае это бесполезно. Я лишь высказываю точку зрения для читателей, чтобы они не были дезинформированы вашими рассуждениями.
Повторюсь. В реализации mbstring разность в скорости незначительна настолько, что не заслуживает обсуждения. В вашем примере со строками вы еще более утрируете, на что я отвечать не собираюсь.

В каждом движке уже существуют те или иные допущения, которые делают жизнь проще и требуют процессора. Вы знаете, что метод вызывается в два раза дольше, чем функция в глобальном пространстве? Вы знаете, что константа, объявленная внутри класса резолвится в два раза дольше чем из глобального скопа? Но тем не менее вы используете классы и объекты? Хотя тут разница в разы. Почему же utf8, который работает незначительно медленнее обычных строк, вы считаете чрезмерно тормозящим, несмотря на то, что его вклад в стройность и безошибочность приложения не менее важна, чем при создании хорошей объектно-классовой структуры?
utf8 всего-лишь кодировка. И когда вы строите приложение опираясь на паттерн проектирования MVC вы его выбираете не потому что это модно, а потому что это оправдано.
Можно конечно вспомнить рекомендации консоциума WC3 и то, что к php6 utf8 станет стандартом для большинства строковых функций. Но не о том было :)

В моих проектах применение юникода оправдано. В проектах Malerok — нет. Не понимаю почему нужно было устраивать какое-то скрытие покровов и выискивание истин.
В чем MVC оправданней utf8? Утверждениями я тоже могу сыпать, я все еще не услышал от вас ни одного аргумента среды выкриков и лозунгов.
Для меня аргументом против cp1251 является уже то, что редакторы в которых я работаю его даже и не знают. Мне этого сполна хватает.
Текст на страницах веб-сайтов — мелочь, в сравнении с их общим весом. Тем более не весь текст, а лишь кириллица.
Пожалуй аякс это один минус который действительно есть, но для этого в запасе iconv(); возможно я и не прав, но мне очень даже хватает cp1251
UFO just landed and posted this here
Аякс — это минус? :)

Знаете, однажды я писал некий интернет-магазинчик. Код я тогда писал в WebDevStudio. Проект «привычно» писался в cp1251, тем более что WDS UTF-8 не понимал. И вот я добрался до работы с корзиной, обновлением суммы заказа через аякс и прочим мелким (но крайне приятным фишкам). Я тогда еще даже jQuery не использовал (хотя уже изучал, просто не до него было).

И тут у меня начались проблемы с кодировками. На странице cp1251. Но аяксом уезжает UTF. Но PHP-шные скрипты тоже в cp1251, поэтому нужно декодировать. И база тоже cp1251. А потом надо результат странице отдать. И тут начинается история с кодировками еще раз. В конечном счете я эти проблемы то решил, но путем неимоверного количества подпорок и костылей.

Проект проработал в сети без малого год. Выпилили его по политическим мотивам.

Но в следущем проекте под давлением коллеги я перешел на UTF-8 и с тех пор ничуть не жалею. Не экономьте на байтах.
Для вас глупость это слово «сегмент» или «символы», обосновывайте свой ответ или не пишите таких вещей
Для меня глупость в словах что cp1251 дает экономию трафика по сравнению с utf8. И то и другое однобайтовые кодировки. Более того внутреннее представление строк во многих современных системах это unicode и тем самым вы получаете дополнительные потери на перекодировку.
Вы сами видимо не читали информацию по предоставленным мне выше ссылкам.
поддерживаю.таскать кучу лишних данных пользователю, бросать их из базы и обратно, да ещё терять серьёзно производительность при работе со строками, только ради слова utf.
недавно пришлось переделывать корпоративную cms на utf-8, понадобилась одновременная поддержка кирилицы и итальнского, заняло часа 2-3 — конвертнул базу, рекурсивно конвертнул файлы, добавил iconv для ajax и xml, заменил строковые функции, поправил заголовки. Немного, зато остальные проекты бегают значительно быстрее без utf там где он не нужен.

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

p.s. ну хоть кто-то ткните меня где я не прав?
Представьте, что проект вышел из под вашего контроля до того, как потребовалась utf8 — уверены, что какой-нибудь фрилансер тоже допустил бы только одну ошибку при конвертации, не зная вашего кода, как свои 5 пальцев (например, используются ли где-то в нём регулярки)?
я сразу написал (корпоративную cms), код не мой, а писался на протяжении нескольких лет разными людьми начиная со времён php4. ни о каких как пять пальцев разговора быть не может, любой код забывают через некоторое время даже авторы. другое дело сколько точек входа, например сомописная escape вместо htmlspecialchars, который принимает несколько параметров.
а плохой код и плохих программистов не спасёт даже utf
Минус очень простой: в тот момент, когда вдруг потребуется использовать не-кириллические символы, Вы огребёте ОФИГЕННЫЙ геморрой.
Спасибо за статью, если бы попалась мне лет так 5 назад, может быть не совершал многие ошибки. Всем начинающим PHP-программистам будет полезно
Грамотные выводы.
Разделяю мнение автора!
Довольно странно было читать фразы типа «функция нашлась parse_str/parse_url», это что-то из разряда «а в языке ведь есть стандартные функции 0_о».

По поводу использования php 5.3 — ринуться переводить на него существующие проекты сразу же вот так — довольно рисковано. Да и главным нововведением, имхо, являются нэймспэйсы, они в общем-то список и открывают.
Не в каждом языке есть те же parse_url и parse_str в нативном виде. В не-нативном я и сам напишу. Читайте внимательнее.

Нейспейсы в 5.3 получились крайне сомнительные. Я высказался о них выше. Сам бы я не стал их использовать. Можно лишь надеяться, что в PHP 6 ситуация с неймспейсами изменится к лучшему и резолвинг символов по синтаксису наконец-то заменят на резолвинг по таблице символов. Без этого неймспейсы не имеют смысла.

А вот анонимные функции уже можно использовать вполне.
В каждом языке свои стандартные библиотеки. Вы призываете пользоваться ими??
Далеко не в каждом они такие обширные и нативные.
С Вашего позволения, расценю это как «да».
(режим К.О.)
Избегайте «преждевременную оптимизацию» и «переинженеринг».

Хороший код, это тот глядя на который хочется сказать «ну и что тут писать то было ?» © не моё, но согласен
Вы забыли главное:

— register_globals = On — зло
— Использовать глобальные переменные без меры — зло
— Использовать extract() — зло
— eval() == evil // ну тут всё ясно
— макаронный код — зло
А макаронный код это что?
з.ы: счастливый вы человек;)
Ну почему, extract и eval для шаблонов внутри соответствующей функции/метода очень даже ничего.
Extract понимаю. Но eval-то зачем?
Если в шаблоне есть управляющие конструкции
А чем include 'template.php' не устраивает?
Попытался вспомнить, зачем мы его юзали, но так и не смог (: Сейчас да, инклудим. Так что беру свои слова про eval обратно :)
Какие еще такие «управляющие» конструкции? :)
Верно подмечено. И это тоже зло.
используя собаку @ в основном при удалении файлов (например):
@unlink($_SERVER['DOCUMENT_ROOT']."/img/file_name.jpg");
UFO just landed and posted this here
Не могли бы вы прищемить себе голову дверью?
UFO just landed and posted this here
Понимаешь, как правило против таких «умников» как ты нормальный стиль общения бесполезен.
Честно говоря про связность тоже не очень понимаю. Ну вот возьмем например Doctrine или что-то в этом роде — туда тоже прокси-объекты фигачить?
Вы никогда не отказывались от одних инструментов в пользу других? Например с Doctrine вы посреди проекта можете упереться в скорость.
Малой кровью все равно не избавиться от нее будет. Или где-то еще DQL раздают?
Что мешает вам сделать интерфейс используя такой же чейнинг, если он вам так нравится? Потом на этот чейнинг нанизаете то, что надо.
Видимо имеется в виду спагетти-код. Они когда варятся перемешиваются сильно.
в контексте php это когда ты открываешь index.php в своем любимом редакторе, и видишь все: css, html, php, sql.
Не совсем. Макаронный код это код без четкой логики и структуры. Вот phpBB на мой взгляд хороший пример.
Ну не скажите. PhpBB 2 этто была первая пхп-штуковина, в которой я разбирался годы назад. Ставя на него «моды» я и начал учить язык)
Там все очень просто по-моему.

Хотя я не хвалю конечно. Исходники IPB того же куда приятнее читать.
По-моему процесс установки модов — и есть отличный пример убогости phpbb
Я же сказал — не хвалю. Но и говорить что там каша полная не стоит. За настоящим спагетти обратитесь к PhpNUKE :)
Что Вы хотите от PHP-Nuke. Это одна из старейших CMS. Она создавалась в те далекие времена, когда о вордпрессах и друпалах еще никто не думал :)
PhpBB тоже не молод, а вон от него что-то хотят)
Ещё некоторые умудряются картинки выдавать пхп-кодом, прямо в нем их прописывая в виде base64.
Для нового проекта с нуля 5.3 — самое оно.
Но если есть много старого кода, последний php, в отличие от 5.2, может банально засыпать предупреждениями «Deprecated».
Deprecated-ы легко выключаются. Такое отключение, конечно, надо делать осознанно, но это вовсе не причина не использовать 5.3.
Вы знаете, это все хорошо, но это уже детали языка :).

А вот с чем у многих проблемы, о чем мало кто пишет и что профессионалу знать действительно надо:

— понимать, как работает веб, его stateless-суть, знать протокол HTTP
— понимать в общих чертах, как работает PHP изнутри (и почему opcode cacher обязательная штука)
— понимать в общих чертах, как работают базы данных ((а) — работа с реляционной моделью, нормализация, join-ы; (б) производительность — зачем нужны индексы и как они работают, btree vs hash, чтение и анализ план запроса)
— понимать в общих чертах, как работают многозадачные ОС (context switch; уметь оценить, во что упираемся — cpu/ram/hdd/network)
— уметь оценивать порядки времени и сложности (проверочный вопрос — расставить по скорости: include файла с array()-конфигом, парсинг ini-файла, чтение конфига из MySQL)
include
парсинг
чтение из MySQL

Такой правильный порядок по уменьшению скорости выполнения?
Ох, как же вы чертовски правы.

Правда забыли добавить главное:

— если хотите делать все хорошо — займитесь изучением архитектуры.
5.3 нужно использовать даже лишь за то, что появился хоть какой-то Namespace!
Кстати, по поводу последнего совета

Читайте код фреймворков, на которых разрабатываете. Это очень интересно и полезно.


Очень часто это бывает не только полезно и интересно — а и вовсе единственный способ понять как та или иная хрень работает. И чем хуже документирован фреймворк — тем чаще приходится пользоваться такой документацией.
> $x = isset($arr['x'])? $arr['x']: null;

Основываясь на собственном опыте, я бы рекомендовал, в частности, использовать статичные вспомогательные классы для доступа к $_GET/$_POST. Очень удобно использовать конструкции типа таких:

$x = Tools::getPOSTVar('varname');

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

static function getPOSTVar($name, $default='') { return isset($_POST[$name])?$_POST[$name]:$default; }
>>В PHP содержится огромное количество нативных (написанных на Си) функций. Их скорость превышает любой аналог

Ага-ага, переписывание на php класса ArrayObject (написанного на С) дало выигрыш в производительности раз в сто :)

На счёт 5.3 — считаю переход преждевременным, полумерой. Вот выйдет 6.0, тогда и можно огород городить, старый код переписывать.
«Далее, создайте свои классы для работы с библиотекой, которые бы проксировали вызовы в библиотеку, но интерфейс этх классов не обязательно должен соответствовать интерфейсу библиотеки. Он должен быть общим и не привязанным к этой конкретной библиотеки, чтобы изменив логику в этих классах, вы могли перейти на другую библиотеку не переписывая сам проект.

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

Эх, с PHP не имею дел уже несколько лет, но на сторонний взгляд — ничего не меняется :)

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

Например, в сообществе alt.net это уже давно само собой разумеющееся — развязывать компоненты, использовать контейнеры, программировать только на интерфейсах (Design by Contract) и писать для всего тесты. Иногда доходит даже до чрезмерной nazi-крайности, но это в разы лучше тонн неподдерживаемого спагетти на PHP.

Хотелось бы, чтобы PHP-мейнстрим принял на вооружение все эти принципы и практики. А язык и его тонкости — это второй вопрос.
Об архитектуре сложно думать т.к. инструментов которые позволяют *полноценно* работать с PHP просто не существует. В итоге чем больше проект, тем больше времени тратиться на синхронизацию моделей (имею в виду UML) и кода…
Ну, я думаю, тут главный инструмент — голова разработчика :)

А в чем именно «сложность думать» об архитектуре?
Предположим, решили грамотно и правильно спроектировать архитектуру используя UML. Набросали каркас. Встает первая проблема — генерация кода, большинство инструментов это позволяют, НО очень малое их число позволяют изменить формат** вывода (т.е. оформить код в соответствии с нужными требованиями). Досадно. Придется исправлять вручную или оставить как есть.

Реализовали каркас, добавили несколько методов (в коде) и классов/интерфейсов. Вторая проблема — а как обновить модель? Часть инструментов это позволяет, НО при этом выясняется что часть информации из модели теряется (а мы старались, делали)… тот же EA*, например, полностью проигнорирует типы аргументов методов (проблеме несколько лет — исправлять её похоже никто не собирается) — придется их восстанавливать. Можно конечно изменять вручную, но это не оправдано и не думаю что кто-то будет это делать для больших проектов (со временем что нибудь забудем и получим расхождение модели и кода).

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

А вот теперь главный вопрос — оправданы ли все эти затраты? По-моему — нет.

* — Enterprise Architect — самый дешевый моделер с возможностью настройки настройки формата файлов (вроде простая функция, но её нет во многих инструментах)

** — это тоже придется сделать вручную, хотя и один раз (но зато он может занять много времени).

P.S. В ближайшее время собираюсь попробовать Eclipse + Papyrus + Acceleo может и получится что нибудь приемлемое для практического использования.
А, ну вы говорите про отсутствие средств. Так то согласен — если, например, Visual Studio отражает все изменения в диаграмме классов, то не знаю, есть ли для PHP подобные инструменты (но, думаю, где-то должны быть).

А менять модель, которая обновляет код — вот этого я не хотел бы в своем проекте. Мало ли что напортачит :) Впрочем, не работал с этими утилитами, поэтому деталей не знаю.

К слову — а так ли нужны эти диаграммы, если все есть в коде?
> Visual Studio отражает все изменения в диаграмме классов, то не знаю, есть ли для PHP подобные инструменты (но, думаю, где-то должны быть)
Если вы про дерево классов и методов — то да, а вот если про UML — то нет.

> А менять модель, которая обновляет код — вот этого я не хотел бы в своем проекте.
На самом деле очень удобно — добавили классы/интерфейсы/методы их каркасы будут автоматически сгенерированы — останется только наполнить их кодом.

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

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

Принято, но как бы это сказать… По-моему, человек, умеющий хорошо (ключевое слово) спроектировать архитектуру или «перерос» PHP («язык и его тонкости — это второй вопрос», но за, скажем, python или ruby платят, как правило, больше) или вынужден поддерживать огромное количество «живого» (не понятно как :) ) legacy кода, недокументированного, не охваченного тестами и т. п., переписать который с нуля нет возможности (времени, бюджета и т. п.) А для новых серьёзных проектов PHP выбирают всё реже, зачастую без каких-либо оснований, кроме мнения «PHP язык для быдлокодеров, а там где в серьезных конторах он используется, то или не на критичных участках, где и былокод пойдёт, лишь бы через раз работало, или недоразумение/распил бабла, или legacy.

>Ровно как отсутствуют предпосылки изначально изучить и следовать принципам SOLID.

Вот это точно, первый раз если не увидел эту аббревиатуру, то узнал её значение. Но и беглое гугление по „+solid +php -border“ (последнее чтоб отделить CSS) ничего толком не дало, так что простительно, наверное :) То есть о хорошем проектировании архитектуры приложений на PHP практически не пишет никто. В учебниках хорошо если вообще про ООП и паттерны вспоминают
«То есть о хорошем проектировании архитектуры приложений на PHP практически не пишет никто. В учебниках хорошо если вообще про ООП и паттерны вспоминают»

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

По поводу legacy-проектов — это да, такое на практике встречается часто. Однако для Greenfield-проекта, я сейчас тоже не выбрал бы PHP по целому ряду причин (видимо, и правда, из него вырастаешь — сейчас имею дело только с .NET, RoR и Python — первый особо крут в плане возможностей архитектуры и языка, последний — неимоверно крут и лаконичен как язык), однако считаю, что хорошую архитектуру при желании можно построить и на нем.
Плохо или хорошо, это факт. Увы приложений написанных на РНР, глядя на которые хочется сказать: «Да, это оно.» в буквальном смысле капля в море. Причина даже не в том что это сложно или легко, просто в 99% приложений это не нужно, и вполне хватает «спагетти-быдлокода»
>Вот это то как раз и плохо. Про архитектуру же в целом пишут очень много — но это уже намного сложнее — читать про нее на примере других языков и применять на PHP, особенно для начинающих.

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

>однако считаю, что хорошую архитектуру при желании можно построить и на нем.

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

Цена зависит не только от предложения, но и от спроса — спрос на PHP-приложения также намного больше, чем на другие. Вероятно потому, что развернуть и администрировать инфраструктуру для PHP, например LAMP, проще, чем под питон или руби и, как следствие, хостингов под него больше, причём подавляюще, и они дешевле (речь идёт о задачах, для которых хватит виртуального хостинга, проблему масштабирования опустим для ясности :) ). То есть, если даже заказчику «просто нужен сайт» и предлагаешь ему на выбор реализовать его на PHP или python (считаем, что разработчику всё равно на чём писать), объясняя ему последствия выбора (цены на хостинги, например, или на администрирование и, естественно, никто не будет говорить: «на пекепе я напишу говнокод, а на питоне конфетку», да и писать тоже), то вероятность выбора PHP, по-моему, побольше будет

>как будто что-то может помешать его написанию

Бытует мнение, что некоторые языки стимулируют к написанию быдлокода, а некоторые стимулируют к обратному. В принципе, доля истины в этом мнении есть :)
Сколько не пробовал найти код в репозитории PEAR, постоянно попадается код под PHP4, который под PHP5.2 сыпет массу ошибок. Тех же нотисов, а иногда и варнингов.

В общем совет на счет PEAR я не поддерживаю. Уже достаточно на этом наматерился.
Классы в PEAR достаточно хорошо протестены, у меня лично в основном выдают сообщение о том, что запрещено создавать объекты с помощью =&new, который, тем не менее, работает для обратной совместимости. Поэтому пока свежие классы в стадии альфы (как тот же Http_Request2), старыми можно пользоваться, а сообщения давить с помощью изменения error_reporting.

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

Кэшна, было бы лучше использовать компоненты из Zend_Framework, если бы они, проклятые, не тормозили как старые клячи.
Я со всем согласен. Но если классы PEAR давить с помощью error_reporting, то и у себя в коде можно бревно пропустить. А это очень опасно, особенно, когда на продукте, в который ставишь библиотеку из PEAR работает целая компания.
Ну так это же надо правильно делать: сохранили старый error_reporting, убрали ненужный уровень препреждений (не помню, notice это или варнинг), вернули старый. Всё это выделяется в отдельный класс.
Ни в коем случае не советовал использовать PEAR. PEAR надо знать и уметь с ним обращаться, а использовать или нет — это дело каждого. За все время нормаольно использовать его у меня получилось лишь раз.
Я бы ещё добавил, что сайтец phpclasses ни в коем случае нельзя использовать, есть вы не уверены, что уже поискали все более адекватные альтернативы и взвесили за и против использования кода с phpclasses против написания собственного. И то, если вы берете класс с phpclasses, нужно сразу лезть внутрь, читать его и править, и дальше держать как свою собственную библиотеку, хоть и основанную на чужом коде.

Искать готовые решения в сто раз лучше в Гугл Директори, чем на phpclasses.

Ещё сразу отмечу, что оператор @ можно использовать. Например, та же функция parse_url выкидывает варнинг, если не смогла разобрать, что ей подсунули. Вам это надо? У меня, например, все варнинги валятся на почту. Отсюда мораль — варнинг давить с помощью @, правильность парсинга проверять сравнением ===false.
а почему бы не проверять аргумент перед тем, как скармливать его функции?
На что проверять, на правильность синтаксиса? А в чем тогда смысл использования parse_url, если я сам предварительно разберу этот урл?
Соглашусь на счет phpclasses. На phpclasses.org код крайне сомнительного качества.
Это как страшилки в кругу у костра;)
Ещё добавлю, что кроме E_ALL стоит использовать PHP_Exceptionizer от Котерова (придется чуть допилить для PHP 5.3). Таким макаром, мимо нотиса не удастся пройти, даже если он случился перед перенаправлением на другую страницу.

Насчет cp1251 спорный момент. Например, накодили вы интернет-магазин, и тут выяснилось, что Яндекс.Маркет принимает только виндовую кодировку. Потсоны, подскажите, как выкручиваетесь в таких случаях? На кого сваливаете ответственность за левые символы в описаниях продуктов, которые из утф в 1251 не перекодируются, особенно учитывая, что iconv, встретив такой символ, объявляет забастовку?
Яндекс.Маркет в данном случае — абстрактный пример: судя по всему, он всё-таки поддерживает утф. Но кроме него, есть ещё всякие 1С, Аксапты и прочая.
В экспортируемые форматы можно приводить как душе угодно, используя iconv, например. Эти продукты ведь не html-страницы грабят.
Я специально для вас написал, что iconv() на символе, которого нет в целевой кодировке, перестает конвертить. Причем в php нет возможности изменить это поведение, в отличие от утилиты командной строки iconv.

Мне было бы интересно услышать мнение тех, кто реально это делал, а не теорию вопроса.
А пробовали методы конвертации из библиотеки mbstring?
Да, у меня даже где-то стоит алгоритм типа «если iconv облажался, делаем mb_convert». У него тоже есть свои затыки, сейчас сходу не вспомню.
Буду вам крайне благодарен если уведомите меня о случае с mb_convert когда вспомните.
А, нет, на первый взгляд не совсем уж беспомощно конвертит:

Norge ?r ett litet land, som ?nd? har en l?ng och
Ох, господи, красотища, хотя //TRANSLIT и не всегда работает так, как я считаю правильнее. Неужели оно там всегда было? Спасибо, добрый человек.
Пожалуйста :) Да сколько помню эту функцию, так всегда было это описано в мануале.
По поводу pear можно поспорить
+ это или — Реализация шаблонов и класса взаимодействия с БД очень тяжелая
Автор не перепутал «связность» (Cohesion) и «связанность» (Coupling) по тексту? Ибо высокая связность — это плюс, а вот связанность — наоборот
Про РНР 5.3 заикнулись, а конструкцию $x = isset($arr['x'])? $arr['x']: null; привели для более старых версий… Правильней было бы $x = isset($arr['x']) ?: null;
$x = isset($arr['x']) ?: null;
равносильно
$x = isset($arr['x'])? true: null;
Sign up to leave a comment.

Articles