Как стать автором
Обновить

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

Реальная польза, например, в получении необязательных параметров из запроса ($param = @$_GET['param']).
Но это не значит, что так и нужно писать! =)

Т.е. я хотел сказать, что во многих случаях действительно «черт с ним».
Для таких случаев использую empty и isset. Как-то некомфортно присваивать чему-либо неинициализированные переменные.
громоздко и не практично
Передается число. Среди возможных значений — 0. Нужно быть абсолютно уверенным, что получено именно то значение, которое ввел/выбрал пользователь. Перепутать с неинициализированной переменной нельзя. Как это реализовать негромоздко и практично?
if( isset( $param = @$_GET['param'] ) )…

isset. А о чем мы до этого говорили? :-\
слив засчитан
можно присваивать по ссылке:
$param =& $_GET['param']
тогда, если param не задан, то в переменной будет null
кстати, isset($param) в данном случае вернет false
Т.е. $param будет содержать null, но при этом будет считать неинициализированным?
isset() возвращает false, если в переменной null, см. мануал
Спасибо, никогда этого не замечал. Неожиданное поведение, возьму на заметку.
$param = isset($_GET['param'])? $_GET['param']: 'default';
например в этом случае:

if (@(include 'somefile.php')!=1){
echo 'тот-то файл не найден';
} else {
echo 'тот-то файл подключен';
}

если включен вывод Warning'ов, то в этом случае всё пройдет чисто ^_^
А почему файл может быть не найден? Вы же не будете инклюдить абы что. Значит, если есть инклюд, то должен быть и файл заранее создан. Все-таки, там код лежит, который исполнится с теми же правами, что и весь остальной.
а если это необязательный модуль?
Ну тогда хотя бы if(file_exists(...)). А по уму, так вообще неплохо бы проверять владельца и права на файл и в принципе не инклюдить то, на что могут быть права на запись у кого-то, кроме владельца.
file_exist породит запрос к файловой системе — и если у вас это разовая операция на страницу — куда ни шло — а если множественная — будет ОЙ. Я считаю. что собака уместна в тех случаях, когда вы ПРИНУДИТЕЛЬНО обрабатываете ошибку сами.
file_exist породит запрос к файловой системе

А include?
Вообще-то я не имел ввиду в данном случае инклуде, скорей я имел ввиду просто чтение какого-то файла с данными например. Что касается вашего вопроса — то у вас будет ДВА запроса к файловой системе на один файл, о чем я собственно и говорил. Тогда как если просто инклуд, то запрос будет один.
Лучше проверить файл вплоть до прав доступа. За уверенность, что я инклюдю именно тот файл, который должен быть с тем содержимым, которое должно быть (к вопросу о правах доступа), то несколько лишних проверок — не такая уж высокая цена. Экономия на одном системном вызове — это несерьезно. А если их намного больше одного, это уже другой вопрос — почему в проекте так много инклюдов и нормально ли это вообще?
Помоему проверка у вас стала самоцелью. Инструмент есть и не беда его использовать ОСМЫСЛЕННО. Если вы следом всеравно делаете проверку на ошибку, то зачем городить десять проверок, вместо того, чтобы сделать одну?
Что Вы узнаете, если инклюд не удастся? Ничего, кроме того, что он не удался. Чтобы узнать причину неудачи, все равно придется делать проверки, только теперь уже в обработчике ошибки. Не будете же Вы выводить пользователю сообщение «инклюд почему-то не сработал, сделай что-нибудь»? Если уж взялись обрабатывать ошибку, то сообщения должны быть полезными. Например — файл не существует, неправильный владелец, неправильные права, неправильная конфигурация пхп и так далее.
Помоему я четко указал, что применять это недо НЕ ДЛЯ ИНКЛУДОВ, может вы всетки прочитаете то, что я написал.
Читаю:
Что касается вашего вопроса — то у вас будет ДВА запроса к файловой системе на один файл, о чем я собственно и говорил. Тогда как если просто инклуд, то запрос будет один.

И когда это мы уже успели сменить тему…
Я написал четко: Вообще-то я не имел ввиду в данном случае инклуде, скорей я имел ввиду просто чтение какого-то файла с данными например. И мой ответ касался именно этого аспекта. помоему это понятно.
Скрипты нехорошо инклудить с собакой — в этому случае любая!!! ошибка (notice, warning, fatal error) внутри этого скрипта будет подавлена. Отлаживать замучаетесь потом.
отличная позиция, напоминает $result = @mysql_query(...) or die('чота случилось не то');

Вместо того, что бы исключить возникновение ошибочной ситуации в любом случае, мы просто кладем болт на тот случай, когда у нас она все таки появляеца. А после ноем, что вот всю ночь дебажили перед дедлайном
В РНР многое сделано для удобства программиста (читай, скорости разработки в ущерб качеству). Оператор @ относится к их числу.
Пресловутый низкий порог вхождения? Не понимаю, для чего делать так, чтоб и кухарка могла писать ПО…
ммм… а если вспомнить, что означает аббревиатура РНР? ;)
Действительно :)
Но теперь это, согласно Вики, расшифровывается как «PHP: Hypertext Preprocessor». Язык вроде бы стал серьезным, а такие странные вещи остались :)
См. нижe
Но это не значит, что так и надо делать! :) Карандашом можно в ухе ковыряться, а можно шедевры создавать.
Согласен. Но все-таки считаю, что лучше убрать возможность писать плохой код в принципе :)
Тогда это будет не РНР :) У него именно такая задача: быстро, просто, дешево. Если у вас другие задачи, то, наверное, лучше подыскать альтернативу. Более строгие языки, например…
Я бы и сам не против. Проблема, что ПХП — это мейнстрим, поэтому с ним неизбежно приходится сталкиваться.
Надо искать альтернативу быдлокодерам, которые работают в комманде, и могут неосилить проект. Пых подходит для разработки всего. Главное что бы руки слушались мозг, а он понимал что и как надо делать.

Дебилы программеры и на яве быдлокод напишут.
Интересно, а к чему отнести 2 забавных случая, когда я тратил по 3-4 часа дебага из за одной небольшой собачки, поставленной каким-то ебланом у инклюда и mysql_query?
Теперь Вы заранее грепаете весь проект на предмет @? В моем случае было такое желание…
У меня все проще. Теперь я не работаю в комманде разработчиков, которые ставят собак в коде ;)
вплане это к скорости разработки, или к качеству все таки?
Использование @ прибавляет в скорости конечно… Я думал, это очевидно :)
секономленные студентом-кодером 5 минут, и потраченные адекватным девелопером 4 часа — это конечно огромная экономия, как в плане скорости, так в плане и стоимости разработки.
Польза оператора подавления ошибок @ будет только в том случае, если Вы твердо решили, что не только пользователь не должен знать о возникшей ошибке, но и Вы сами.

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

Такие случаи редко, но бывают

Приведите, пожалуйста, пример. Не могу сообразить, в каких случаях это может понадобиться.
Пример: жадный заказчик :) «Все работает нормально, у вас интернет сломался»
Сдаётся мне, что ini_set('display_errors', 0);
будет проще поставить, чем расставлять собаки и мешать себе разрабатывать.
Может быть, что ини-сет не сработает? Кстати, перед ини-сетом часто ставят собаку.
ну когда вы действительно плюете на ошибку)) не выводите ее, но и не обрабатываете
Как сказано ниже в примере с jpeg, ошибку можно не выводить, если потом идет проверка полученного значения. А вот в коде, который выполняется просто так, авось все будет нормально — какой смысл? :)
Лень программистов и ничего более.
Пишут люди код по принципу «Ну работает же! Какая разница как.» :)
собака сама по себе не блокирует запись в лог.

но можно написать свой обработчик ошибок, который будет учитывать её наличие…
Например для функций GD вроде imagecreatefromjpeg т.к. пока вы не попытаетесь открыть, вы не узнаете наверняка, JPEG там или нет, а при попытке открытия «битого» файла выдается сообщение об ошибке.
Такой код и ошибку не выдаст и мы точно узнаем, нормальный файл или нет:
$im = @imagecreatefromjpeg($imgname);

if($im)
{
echo "JPEG!";
}
Спасибо.
НЛО прилетело и опубликовало эту надпись здесь
If accessing the filename image is impossible, or if it isn't a valid picture, getimagesize() will generate an error of level E_WARNING. On read error, getimagesize() will generate an error of level E_NOTICE.

Т.е. такой же результат.
Если, я например, буду ресайзить картинку, то мне нет нужды делать проверку через getimagesize, т.к. проверку идентичную картика пройдет в imagecreatefromjpeg.
Да-да-да!!! Только для этого случая специально использую, мне просто казалось, что достаточно того, что функция false вернёт, так нет же, еще и варнинг кидает.
К сожалению, GD до сих пор неправильно обрабатывает JPEG файлы некоторых фотокамер, например сделанные некоторыми фотиками CANON и телефонами фирмы ALCATEL отдельными моделями. При том что вам эта команда покажет, что файлик нормальный.
в таком случае проще в set_error_handler, кидать по варнингу эксепшны. Доказано вообщем-то практикой, что в подавляющем большинстве случаев, если у нас варанинг — дело, для куска кода, что ниже… вообщем-то плохою.
НЛО прилетело и опубликовало эту надпись здесь
Спасибо, действительно в таких случаях удобнее будет использовать @, чем понижать логлевел.
Возможно, я ошибаюсь, но не лучше ли понизить логлевел перед этой функцией, а потом повысить его? Насколько я знаю, @ довольно ресурсоемкая операция (хз почему так — не копал особо).
Этот оператор называют ресурсоемким именно потому что он изменят 2 раза меняет логлевел (сброс + восстановление). Но надо понимать, что ресурсоемкость вещь относительная. Одно дело, если при инициализации будет один вызов наподобие @$_GET['key']. И совсем другое, если подобные финты будут выполнятся пачками, нечто вроде @mysql_query(...) вообще саботаж…
И совсем другое, если подобные финты будут выполнятся пачками, нечто вроде @mysql_query(...) вообще саботаж

Почему? mysql_query должен выполняться всего несколько раз и возвращать массив значений. Множество раз он может выполняться, только если в цикле вытягивать из базы по одной строке, за что и так надо бить по пальцам :)
пример с mysql_query к тому, что скрытие ошибок функций для работы с БД — вредительство.
Потому что однажды я просидел 4 часа, ковыряя код, раставляя вар дампы, и проходясь уже в конце по проекту дебагером что бы найти эту е$!#%ую строчку, дада, именно ту, в которой было $result = @mysql_query(...).

Нет, если бы в этом месте мы всегда бы вытягивали данные одни и теже — потребовалось бы в десятки раз меньше времени. Но данные вытягивались все время разные. А потерю инфы можно было заметить только черех 4-5 скачков по функциям, где система, которая ожидала эти данные, их не получала и просто падала…
кроме функций GD использую также для file_get_contents, которая при ответе сервера 4XX выдает Warning
в рабочей копии надо выводить варнинги, в продакшн — игнорить или логать
при генерации картинок — также логать
оператор @ — нужен — для перехвата ошибок.
Многие функции в php — перед ошибкой не генерят эксепшены.
Пример:
$f = @file_put_contents('/tmp/date', $source);
соответственно если прав нету на запись файла или ещё какие проблемы — то будет варнинг.
Поэтому лучше перехватывать такие ошибки и генерить эксепшены.
Ну к примеру mysql_connect — генерит варнинг если сервер не доступен. Таких много функций. :) Не говоря уже о GD — если к примеру загрузка картинки — а картинка битая :).
Короче @ — это костыль php
Если бы каждая функция для php как к примеру Pdo, генерили эксепшены то тема обсуждения не была бы актуальна.
А кто мешает обработать результат file_put_contents или mysql_connect?
А варнинги? А варнинги очень нужны разработчику, а вот их вывод на продакешен — моветон.
>оператор @ — нужен — для перехвата ошибок.
не нужно нести бред
есть set_error_handler это раз
есть file_put_contents() or throw new exception()
Можно использовать при подключении к БД, чтобы в случае ошибки вывести красивую страничку, а не засорять умы простых смертных непонятными строчками.

$sql = mysql_connect() or viewErrorPage('Не удалось подключиться к БД.');
Извиняюсь, поспешил. Так:

$sql = @mysql_connect() or viewErrorPage('Не удалось подключиться к БД.');
Т.е. в случае, когда возвращаемое значение обрабатывается. Согласен, в этом случае полезно.
давно уже пора использовать pdo и не засорять умы простым и не очень смертным
специально для таких случаев есть.
__construct() throws a PDOException if the attempt to connect to the requested database fails.

ну а если не pdo не хватает познаний то есть or trigger_error() c последующим set_error_handler()
PDO — это DBI для PHP? Описание как-то не радует, mysql_* все-таки поприятнее. Тем более, если не нужно ничего, кроме MySQL'я.
ну думаю что приятно заниматься слешированием кавычек в запросах через mysql_real_escape_string когда достаточно сделать bindParam но самое приятное то что pdo — обьектный а значит можно изменять поведение класса. а mysql_* это очень старая штука расчитаная на mysql 3.23, раз уж хочется простоты то следует использовать mysqli (тк поддерживает фичи «новых» мускулов)
по теме
ru.wikipedia.org/wiki/PHP_Data_Objects
о php PDO по русски с примерами
Спасибо за ссылки. Просто к подобным абстракциям у меня негативное отношение еще с перловых времен. Дело привычки :)
PDO всего лишь один из вариантов и не надо его кононизировать. Если вам он кажется единственно правильным, то ровно также многим не кажется. И дело тут не в уме и способности изучить.
не правильным, а наиболее полным вариантом.
вообще не мешало бы к критике приложить свое мнение по поводу того что является верным и почему вы не согласны
ps кононизировать -> канонизировать
Моё мнение простое — PDO совершенно избыточное решение для PHP проектов. Выигрыш от использования PDO никак нельзя назвать ощутимым. Наличие собственного простого класса для абстракции базы полностью способно покрыть все потребности любого проекта, это решение значительно быстрее по времени работы и проще в освоении. PDO не дает ничего такого, чтобы я на данный момент испытал потребность его использовать.
А давайте мы определимся о каких PHP проектах идет речь. Хотя нет, плевать что за проект перед нами…

Ведь свой велосипед, хоть кривой (что-то я пока еще не встречал более адекватных и юзабельных решений нежели тоже самое PDO от велосипедистов на том же слое — отправка запроса\получение результата), и основанный скорее всего на mysql_* — гораздо ближе. Ибо он с первого взгляда выглядит идеальным, быстрым, и в нем нет ничего-ничего лишего.

А выигрышь от PDO — это вопервых стандартная штука, во вторых — на ее реализацию не тратится времени. Ах да, конечно, изучить мануал, который на 20 строчек без примеров — мы не можем. У нас нет на это времени.
Все мы можем изучить. Но инструмент выбирается под потребности, а не наоборот. Так уж случилось, что начинал я давно и никаких таких PDO тогда небыло. Был ADODB например, я в своё время сделал локализованную версию документации и пользовался этой библиотекой во многих проектах, где не надо было задумываться о производительности, главное ведь, что ADODB снимала много вопросов с программиста. Потом стали появляться нагруженные проекты и ADODB пришлось отправить на покой. Потом пришло понимание, что никакие такие объекты при работе с базой данных мне не нужны, потребность во всякого рода хелперах в проектах также стрмилась к нулю. Между тем, был написан в еще до ADODB период некий небольшой класс, который делал ряд вещей, которые были востребованы и удобны в разработке. Да, вы правы, это была всего лишь обертка над mysql, точнее сначала была Postgre. Так вот, к чему я тряхнул стариной? Конечно же PDO смотрелась и в бетах и в релизах, конечно же потом попадались и проекты с PDO внутри. Только то, без чего вы не можете жить для меня совершенно не актуально. Мой код ничем не страдает от того, что PDO не используется. Я превык выбирать инструменты под задачи, а не задачи подстраивать под инструмент.
по времени работы возможно, по ресурсам точно, особенно если использовать индексированный доступ к результатам выполнения запроса. только вот время выполнения sql запроса явно будет больше времени работы драйвера бд.
+ не стоит забывать о стандартности методов и API, этого самописный класс обеспечить не может

Гм, стандартность методов API по отношению к чему? Что вы взяли за эталон?
имеется ввиду что API знает заведомо больше одного человека и не требуется дополнительное обучение
К сожалению, это не так — большинство людей о PDO не слышало, а если и слышало, то не трогало.
Гдеж вы это большинство то берете? Нет, конечно студен-пыхарь то ничего и про программирование не слышал, что не мешает ему писать тонны создавая проекты, которые обреченены умирать. Но адекватному девелоперу не знать что такое PDO даже на уровне «дада, это такая чтука что с бд работает» — как бы несовсем правильно
Вы это расскажите тем, кто приходит на собеседования.
чем же древний mysql_* написанный в процедурном стиле приятнее, более-мение адекватного интерфейса к бд? Или, приходица писать чуточку больше понятного кода, который вас смущает (наплодили понимаешь тут объектов...)
Тем, что мне проще обернуть mysq_* в собственный класс, чем пользоваться PDO. Как я сказал выше, DBI-подобный интерфейс мне не нравится чисто субъективно.
… а шаблонизатор свой не пишете?
На шаблонизатор это не тянет :)
Ну эксепшены вроде только в последней версии PHP появились — так что теперь ошибки надо не проглатывать, а обрабатывать.
Учитывая, что последняя версия пхп вышла ой как давно, а предпоследнюю уже не поддерживают, то «теперь» в данном случае = «давно».
использовал этот оператор только один раз когда надобыло получить какие то текущие данные с сайта а он постоянно падал, вот и приходилось «собачится» )
а в других моментах доверяю сам себе
ставлю собаку тока в одном месте кода — перед unset. иногда бывает, что файлы пропадают:)
unlink конечно же:)
@ — зло в php
он еще и не всегда работает. Например, @imagecreatefromstring все равно кидает варнинги. Очень неприятно. Приходится в определенных местах специально делать set_error_handler.
Вот, кстати, есть такая функция parse_url. Она разбирает URL и возвращает массив элементов урла.

Вот этот код выведет на экран домен:
$parsed = parse_url($url);
echo $parsed['domain'];


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

Например, ругается на

$parsed = parse_url('http://');


Хотя было бы достаточно просто вернуть false. Так нет — кидает нотайс, скотина. И не на всех хостингах вывод ошибок на экран оказывается отключен по умолчанию!

Вот на фига тут перед этой функцией еще фигачить проверку через регулярку, если можно сразу пустить в эту функцию и смотреть, выдало ли $parsed['domain'] или нет? Приходится превентивно «собачить» ее.

Кстати, в последнем примере, по идее, должно было бы вернуть $parsed['scheme'] = 'http' или как-то так.
Помниццо мне, я юзал собаку при выводе GET'a или POST'a в value input'a, то есть допустим при регистрации пользователя, если он что-то не верно ввел — он отдаст те переменные, что он писал до этого… имхо удобная штука…
Не нравитсо — не пользуй
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории