PHP_Exceptionizer: преобразование E_NOTICE в исключения (Exception)

    Очень простая, но полезная библиотека PHP_Exceptionizer позволяет преобразовывать нотисы (E_NOTICE), предупреждения (E_WARNING) и т. д. в исключения PHP.

    // Где-то в начальном коде инициализации скрипта.
    error_reporting(E_ALL);
    if (<is debug mode active>) {
        $exceptionizer = new PHP_Exceptionizer(E_ALL);
        // И оставьте эту переменную, чтобы она не удалялась до окончания 
        // скрипта. Удаление переменной вызовет отключение PHP_Exceptionizer.
    }
    ...
    // Далее можно ловить нотисы как исключения:
    try {
        echo $undefinedVariable;
    } catch (E_NOTICE $e) {
        echo "Notice raised: " . $e->getMessage();
    }
    ...
    // Если вы ловите E_WARNING, то поймаете и E_NOTICE тоже:
    try {
        echo $undefinedVariable;
    } catch (E_WARNING $e) {
        echo "Warning or better raised: " . $e->getMessage();
    }
    ...
    // А можно и не ловить, тогда нотис вызовет завершение программы.
    echo $undefinedVariable;
    


    Библиотеку удобно использовать при разработке и отладке. Как известно, ее лучше проводить в режиме error_reporting = E_ALL и держа в уме, что даже малейший нотис при разработке — намек на фатальную ошибку.

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

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

    Однако существует случай, когда библиотеку имеет смысл включать и в продакшен-режиме. Это — система генерации рассылок. Представьте, что вы написали скрипт, который рассылает письма нескольким миллионам подписчиков сайта, и текст письма генерируется динамически, в зависимости от профиля пользователя или его друзей. Вы можете поймать себя на мысли, что запускать этот скрипт очень страшно… Вдруг там произойдет какая-то ошибка, и миллион человек увидят пустые поля или «скомканное» письмо? PHP_Exceptionizer позволяет заметно снизить этот риск, если вы включите ее в момент генерации письма.

    Скачать библиотеку можно тут: dklab.ru/lib/PHP_Exceptionizer

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

      –2
      О, интересная штука.
        +1
        вот если бы это работало без переустановки error handler-а, тогда да бы цены не было бы этой библиотеке. в таком виде польза сомнительная — код должен выбрасывать исключения, а не ошибки. нотисы должны останавливать dev-скрипт и не должны быть видны на продакшн. пример с расслыкой спама какой-то… грязноватый… если вам страшно запускать такой скрипт то нужно лучше тестировать.
          +5
          писец.
          Полное непонимание зачем нужны исключения.
            –30
            Согласен. Имхо в PHP их вообще не может быть. Там имеет место разьве что си-подобный хендлинг ошибок, но не SEH-подобный, ибо в PHP ООП уныл и не нужен.
              –22
              стадо, может вы меня опровергните, вместо того чтобы тупо минусовать?
                +6
                А Вы можете объяснить чем уныл ООП в PHP? Или вы считаете что ООП языком является только язык с чистом ООП? Как питон примеру, а все остальные унылы?

                Если на практике в PHP реализуемы многие типовые решения на базе шаблонов проектирования, и широко применяются, чем уныл ООП в PHP? С каким задачами в вебе он не справляется?
                  0
                  это питон то — язык с чистым ООП? бггг…
                +5
                "… ибо в PHP ООП уныл и не нужен" — стадо говорит — запарили уже чесать про минусы ООП в PHP. Вам решать что в PHP нужно что нет? Мне лично совсем не мешает.
                  +2
                  Это просто вы пользоваться ООПом не умеете. Даж наличие staticа позволяет мне делать вообще все что моей душе угодно и обмен данных между классами и прочь. Да и чтоуж говорить Код какой красивый и читабельный становится.
                    +1
                    Вот дела. А мы знакомы что вы делаете такие утверждения? Одним статиком вы не реализуете обмен сообщениями между обьектами — что есть как бы корень одна из концепций ООП. Приложение где всё статика — это не ООП приложение. Ваши доводы просто абсурдны.
                      0
                      а пусть человек покажет хороший ОО код, страницы на 1.5 — 2? :-)
                      0
                      а покажите хороший, по вашему мнению, ОО код. страницы на 1.5 — 2.
                        0
                        При классах с static методами невозможны практически все шаблоны проектирования. Что логично.
                          0
                          Уточню, с только static методами :)
                    0
                    Со стороны авторов языка?)
                    +4
                    IntenT, ну почему? Исключения нужны дабы сделать блок кода атомарным. Другими словами, если случается исключение (сбой), то операция (try) прерывается и выполняется действие на случай сбоя (catch), а также действие безусловное к успешности операции (finally). Без них неудобно (практически невозможно) написать устойчивую систему.
                    Исключения в PHP введены довольно поздно, поэтому много существующего кода написано без исключений. Данная библиотека позволяет работать с ошибками как с исключениями, и это я считаю правильно. Ведь по сути даже E_NOTICE это страшная ошибка, если мы говорим о серьезном проекте, в котором опечатка программиста может привести к неожиданному поведению системы, и потере (порче) информации или к её неадекватному изменению.
                    Я считаю надо писать код, который готов адекватно обработать любую ошибку и при этом адекватно воздействовать на модель (к примеру сделать ROLLBACK, сделать запись в лог и завершить работу).
                      –8
                      А что, такие вещи уже в библиотеку выносят? Что будет дальше — библиотека переменных с правильными именами для каждого случая жизни?
                        0
                        Не, по-моему включать такое на все время выполнения скрипта — это не дело, а вот чтобы обойти некоторые проблемные функции php, генерирующие warning'и в достаточно рядовых ситуациях — вполне подходит.
                          0
                          По сути варинг кинутый какой-либо пыховской функции… это в 99% ошибка. По сути, из за нее имеет кидать смысл экспешн. Но кидать его на нотис, или городить try {} catch() {}, на каждой двацатой строчке… немножко неправильно.
                          • НЛО прилетело и опубликовало эту надпись здесь
                              0
                              Т.е. вы хотите сказать, что перед отправкой код на продакшн я буду вычишать половину своего года от трай-кетчев? Отлично. Такими темпами можно дойти и до того, что для дева и продакшна вообще разный код будет.
                                +3
                                Зачем? Можно написать свой exception handler, который будет выводить эти самые эксепшены без всяких трай кетчей
                                  0
                                  Хм, вам не кажется что как-то это не очень логично звучит, сначала написать свой error handler, который ловит ошибки, и преобразует в исключения, а затем exception handler который ловит эти исключения :) для таких целей — почему-бы изначально не написать обработчик ошибок, который например сбивает заголовки переадресации и выводит ошибки на экран.
                                • НЛО прилетело и опубликовало эту надпись здесь
                                    +2
                                    Именно. Потом говорят что php плохой язык, хотя сами «чисто» писать не умеют.
                                      0
                                      Несомненно, хотя на счет варингов не согласен. практически любой варнинг в пхп == ошибка в том же си. Только возвращается не -1, а false. Впринципе кинуть на нее эксепшн — при нормальной ооп-архитектуре, будет даже правильне и проще, нежели передавать коды ошибок и прочее…

                                      А вот в этой «библиотеке», смыла вообще не вижу, ибо уверен, что она будет вопервых развивать неправльное понимания использовании экспешнов да и лично я не знаю что можно в catch поставить если брошен E_NOTICE, как и все те люди которые будут этим пользоваться. В итоге будет получаться код, за который будет хотется долго и упорно избивать разработчиков
                                      0
                                      На самом php.net настоятельно рекомендуют порождать только при ошибках в логике — была передана в функцию строка вместо массива, переданный в метод объект не реализует указанный интерфейс, не удалось подключиться к базе. Ошибка запроса к базе. А никак для перехвата случаев доступа к несуществующему элементу массива, несуществующей переменной и подобных.

                                      К тому же такой перехват ошибок никак не избавляет от засорения ими error-лога.
                                        0
                                        Ну, некоторые эксепшены использует еще для того, что бы проверять введеные пользователем данные…
                                          0
                                          Помню встречал буквально феерический пример проверки введенных данных с помощью исключений :)
                                          try {
                                            if(!isset($_POST['var1']) {
                                              throw new Exception();
                                            }
                                            $var1 = $_POST['var1'];
                                          } catch(Exception $e) {
                                            $var1 = NULL;
                                          }
                                          try {
                                            if(!isset($_POST['var2']) {
                                              ...
                                          
                                      0
                                      Культура кода — это совершенно не то понятие. Культура кода подразумевает логичное размещение операторов.
                                      По описанию видно, что все предназначение либы заключается в дебаге. Кто мне без этой либы помешает включить error_reporting(E_ALL | E_STRICT)?

                                      А в текущем ракурсе — это самое натуральное захламление кода.
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                          0
                                          Xdebug, например, умеет бектрейс выводить. www.xdebug.org/
                                          Да и вообще удобнее в отладке.
                                          • НЛО прилетело и опубликовало эту надпись здесь
                                              0
                                              Мы говорим о сервере, на котором Вы разрабатываете или о гипотетической машине?
                                              Так вот, на последнюю будет проще воткнуть xdebug, чем втыкать в код для расстановки обработчков :)
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                      +1
                                      Таких мест нет. А такое мышление может привести к плохому коду. То что PHP нетипизированный, прощает многие ошибки, выполняет за программиста работу с памятью, абсолютно не значит что, к примеру, надо проверять существование переменной таким кодом:

                                      if($_GET['abc']) {

                                      }

                                      А @ снижает читабельность кода и заставляет интерпретатор переключать display_errors с on на off и обратно.
                                        0
                                        А можно привести пару таких мест?
                                        • НЛО прилетело и опубликовало эту надпись здесь
                                        0
                                        Стоило бы приветсти пример. Что это за функции, которые генерируют warning в рядовых ситуациях?
                                          0
                                          Ну я-же не статью пишу, чтобы к каждому своему слову давать по 10 ссылок на цитируемые источники :) Примеры навскидку — mysql_connect например, невозможность подключения к БД естественно не является рядовой ситуацией, но это не та категория ошибок, которую можно отловить так, чтобы она не появлялась впредь, тоесть даже в идеально отлаженном скрипте такая ситуация может возникнуть, соот-но эту ошибку нужно как-то обрабатывать, дабы не оставить пользователя наедине с «Unable to connect to mysql server...» :) Преобразование в исключение в данном случае полезно, так как позволяет прямо в месте подключения написать локальный обработчик этой ошибки, в блоке try..catch, вместо того чтобы переопределять обработчик ошибок через set_error_handler на созданную зараннее функцию. Из более простых примеров — parse_url например высылает warning если не удалось разобрать строку по компонентам URL, что уж точно не является внештатной ситуацией.
                                            –1
                                            На боевом сервере вывод ошибок лучше отключать :) И лучше конечно использовать свой mysql wrapper, который при невозможности подключения, mysql_connect возвращает false в таком случае, порождает исключение, перехват которого выводит красивое окошко к примеру.

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

                                            Вы же не хотите при использовании MS SQL, чтобы вам убили базу? Он позволяет делать несколько запросов. При наличии SQL Injection достаточен только один update… И перехват исключений в данном случае вас не спасет.

                                            То что у вас возникают warning, это значит что вы плохо управляете данными в коде.
                                              0
                                              Ну хорошо, не вопрос, вывод ошибок можно и нужно отключить, только ошибки от этого не изчезнут, и свой mysql wrapper не избавит от warning'а при невозможности установить соединение с БД. mysql_connect в любом случае и генерирует warning, и возвращает false, мне лично кажется значительно более правильным ориентироваться именно на warning, а не банально его игнорировать, false всетки генерируется функцией как раз из-за того, что произошла ошибка, и в результат нечего больше записать.

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

                                              Где связь между SQL injection и обработкой ошибок? Перехват исключений и защита БД от инъекций — это вообще сущности разных порядков, исключения — механизм ЯП, обработка данных перед записью — логика программы, на этом ЯП написанной, к чему вообще был написан этот абзац?

                                              Ну, каждый волен думать по своему :)
                                                0
                                                Вывод ошибок на боевом сервере следует выключать из соображений безопасности.

                                                Вы правы свой mysql wrapper и не должен избавлять от warning, и Вы никак от него не избавитесь в случае падения сервера. И игнорировать его не надо. Но warning вам не поможет получить уведомление по почте о падении базы даных. Вы же не проверяете error log каждый день. А написание логики обрабатывающей этот false и посылающего уведомление на почту поможет. Вы же различаете еще и контекст, в котором возвращается false и порождается warning? То есть внешние непредоолимые факторы, как падение базы данных, или такие, ошибка программиста из-за неправильно переданных аргументов функции.

                                                parse_url инструмент. Но инструментом нужно правильно пользоваться. Вы же передается в mysql_query() только правильно сформированные урлы, Вы используете в preg_match() только корректные регулярные выражения. И у каждого инструмента есть своя область применения. Всетаки parse_url предназначался больше для обработки уже заранее верных урлов, как например url, по которому был вызван скрипт с parse_url :)

                                                Связь вытекла как раз из parse_url :) Если программист считает не нужным проверять данные для таких функций как parse_url, то он может дойти и до написания кода с отстуствием проверки данных для запросов к базе. И просто перехватывать warning от mysql_query как исключения :)

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

                                                  Сам warning согласен, не поможет, мне поможет блок catch() {}, который поймает исключение вызванное этим warning'ом.

                                                  parse_url инструмент, единственный в своем роде в php, альтернативы ему нет, разве что регулярное выражение или самописная функция, но этот инструмент достаточно простой, просто он был одним из первых что всплыл в памяти, и его можно заменить, а вот например реализовать самому что-то вроде getimagesize уже врядли получится малой кровью, также как не получится найти ей альтернативу, разве что проверять что присланный файл — изображение через exif, но exif — это доп.расширение, которое должно быть включено. Причем getimagesize генерирует два типа ошибок для разных ситуаций, и игнорирование ошибки, простой проверкой возвращенного значения, приведет к тому что обе ситуации будут обработаны одинаково.

                                                  Ну я уже написал свою позицию на этот счет, parse_url — функция, которая сама проверяет данные.

                                                  Возможно.
                                              0
                                              Из более простых примеров — parse_url например высылает warning если не удалось разобрать строку по компонентам URL, что уж точно не является внештатной ситуацией.
                                              А смотря как и зачем мы эту строку парсим. Вполне может быть что эта критическая ошибка, дальше которой продолжать выполнять код смыла то и не имеет.
                                                0
                                                Ну может быть, а может и не быть, а функция-то в итоге одна :) чтобы избежать этого ее поведения — нужно или отлавливать ошибку, или переписывать оную функцию с нуля.
                                                  0
                                                  Умный знает как выбраться из сложной ситуации, мудрый знает как в нее не попасть. (с) Конфуций

                                                  Зачем отлавливать ошибку, и исходя из нее чтото делать, когда гораздо эффективной просто не допускать такие ошибки.
                                                –1
                                                У mysql_connect можно использовать собачку и проверять результат)

                                              0
                                              достаточно «собаки». @fsockopen() ... if (!$fp) {case $errno:}
                                                0
                                                Достаточно, такого рода функции в php изначально предназначены для такой работы с ними, исключения просто делают этот процесс удобнее.
                                                В случае $result = @fsockopen(...); если ошибка не будет обработана сразу-же после открытия — ее практически невозможно будет отловить.
                                                В случае когда $result = fsockopen(..); высылает исключение — программист обязан будет его обработать, на месте, или выше по иерархии вызовов, в любом случае его нельзя будет проигнорировать.
                                              +1
                                              Переопределение обработчика ошибок = несовместимость с SimpleTest.
                                                0
                                                у нас в mzz обработчик переопределён и мы пользуемся simpletest'ом.
                                                  0
                                                  Юзаю последнюю бету, в которой уже нет совместимости с php4, все замечательно
                                                  +12
                                                  А можно так:
                                                  set_error_handler( create_function( '$x, $y', 'throw new Exception( $y, $x );' ), E_ALL );
                                                    +12
                                                    обязательно это дело упакуйте в библиотеку и напишите статью об этой 1 строке!
                                                      0
                                                      Ну там в библиотеке как бы не одна строка, а три:
                                                      — отслеживание фильтра, какие ошибки преобразовывать в исключения, а какие — нет;
                                                      — идеома «выделение ресурса есть инициализация», в результате чего преобразователь нотисов в исключение автоматом отключается при выходе из области видимости текущего блока;
                                                      — иерархия «серьезностей» ошибок.
                                                        0
                                                        а, 3… ну да, это всё решает.

                                                        ps: даже если на секунду представить, что код библиотеки хоть немного может быть ценен обществу — глупые примеры в посте перечёркивают все твои старания и рождают волну оффтопа.
                                                    +3
                                                    У Димы уже не осталось идей и поэтому он пиарится как может?
                                                      –2
                                                      Дима что-то исполняет, хотя если уж очень хочется генерить экспешини на ошибках вешаем свой обработчик ошибок, который генерит.

                                                      И дело в шляпе… для удобства проверять в своем обработчике уровень error_reporting, если 0 — молчим, если нет — генерим.

                                                      и получится что если нам надо дебагерить — оно будет кидать исключения, если поставили error_reporting=0 будет молчать — все как надо…

                                                      сделали из мухи слона :) ппц
                                                        0
                                                        я подобной же техникой пользуюсь с 2004 года какбе :-)
                                                      +1
                                                      Ничего не имею против Дмитрия, но действительно, оборачивать в библиотеку элементарные вещи думаю не стоит (handler'ы это ведь средства языка).

                                                      То что исключения надо использовать только на девелоперской версии это величайшее заблуждение, т.к. они принципиально отличаются от сообщений об ошибках.
                                                        0
                                                        /*Предыдущий пост случайно отправился раньше времени.*/

                                                        Это принципиально другой подход нежели вывод ошибок, хотя для вывода (логирования) тоже их можно использовать). Блоки try могут быть вложенными: всю бизнес-логику следует обернуть в try который будет выводить (записывать) так называемые Uncaught exception, т.е. непойманные исключения. Между тем, внутри этого блока можно делать сколько угодно других try блоков и обрабатывать те или иные исключения как штатные ситуации. Чтобы не быть голословным насчет штатных ситуаций, приведу пример. Предположим, нам необходимо разобрать query-string на параметры (забудем про массивы, не в этом суть):
                                                        $pairs = explode('&',$querystring);
                                                        $array = array();
                                                        foreach ($pairs as &$pair)
                                                        {
                                                        $e = explode('=',$pair);
                                                        $key = $e[0];
                                                        $value = isset($e[1])?$e[1]:'';
                                                        try {$value = unescape($e[0],'UTF-8');}
                                                        catch (Exception $e) {$value = '';}
                                                        $array[$key] = $value;
                                                        }

                                                        То есть, мы в случае, если декодирование не удалось (ошибка кодировки), присваиваем пустоту.
                                                        Мощный инструмент эти исключения я вам скажу. Обязательно попробуйте, те кто не пробовал.
                                                          0
                                                          parse_str никак? :)
                                                            0
                                                            Это лишь пример использования исключений, но не реализации данной операции, тем более parse_str безралична кодировка (не понимает %uXXXX).
                                                        +1
                                                        ну и апофеоз обсуждений:
                                                        wiki.agiledev.ru/doku.php?id=ooad:exception_using
                                                          –5
                                                          Ой, а я предпочитаю ошибки не ловить, а сразу грохать скрипт))

                                                          p.s. Автору огромнейшее спасибо за клевую библиотеку SimpleDB)) Имхо одна из наиболее удобных (хотя, конечно может потреьовать определенной доработки)
                                                            +2
                                                            почему не PDO?
                                                              –3
                                                              У PDO только 1 плюс: встроенность в php. Синтаксис ужасный, у меня руки отвалятся столько лишнего кода писать, и SimpleDB поддерживает больше плейсхолдеров (хотя можно и расширить список), более удобный набор функций.

                                                              Насчет синтаксиса — этот момент принципиальный)) Даже писать 2 раза prepare/execute — уже лишнее.
                                                                +1
                                                                какого ещё лишнего кода???????
                                                                уже почти 4 года на PDO, всё там чудесно.

                                                                ps: мсье вкурсе, что его можно расширять?

                                                                pps: хотелось бы примеров таких ужасающих недостатков PDO.
                                                                  0
                                                                  Ну видимо расширение или раздувание кода для него, так же как и для многих (сталкивался очень часто с этм), это написание нечто большее нежели написании mysql_query, DB::query, $db->query, $model->query и в скобочках «большой и непонятный запрос» со включением всех переменных. А в пдо же что бы все красиво и грамотно, для этого надо строчек 10 выделить… пока стейтмент создать, пока сам заброс быстренько набросать. пока забиндить значения к нему… Видимо для многих это сложно.
                                                                    0
                                                                    можно расширить класс PDO примерно таким вот методом:

                                                                    public function getRow($query)
                                                                    {
                                                                    $result = $this->query($query);
                                                                    $row = $result->fetch();
                                                                    $result->closeCursor();
                                                                    return $row;
                                                                    }

                                                                    и начать радоваться жизни :-)

                                                                    камень не в ваш огород, просто показал человеку на чей коммент я отвечал — вы-то понимаете что PDO это нямочка :-)
                                                                    0
                                                                    приведите, пожалуйста пример кода на PDO, хотя бы несколько строчек, а я скажу, что не так))

                                                                    p.s. То, что парой комментов ниже написано — лишний изврат;) Ибо $query как я понимаю это запрос, к нему еще отдельно наджо делать bindParam()
                                                                      0
                                                                      не нужно делать никаких bindParam — это готовый plain запрос.
                                                                      а по поводу кода — вы сказали, что пдо неудобен — с вас и прув.
                                                                      если не хотите ничего показывать и приводить — так и скажите, я к этому был готов изначально.

                                                                      ps: перед продолжением дискуссии, если таковая будет, настоятельно рекомендую перечитать документацию по пдо — или вы её в своё время невнимательно читали или всё действительно так сильно изменилось (впрочем, я, как человек, пользующийся им с первых стабильных версий пхп5 этого не заметил)
                                                                        0
                                                                        Послушайте, если бы я писал plain-запросы, я бы написал объектную обертку с lazy connect, и обработкой ошибок вокруг mysql_*(), зачем мне тогда PDO?

                                                                        К хорошему привыкаешь быстро, мне нужныв именно плейсхолдеры, пистаь ручками mysql_real-escape_string(...) нет желания.

                                                                        Пруф? Чем замените в PDO вот это?

                                                                        $db->execute('INSERT INTO ?t (?#) VALUES (?a)', $table, array_keys($data), array_values($data));

                                                                        Или вот это?

                                                                        $records = $db->getCell('SELECT COUNT(*) FROM ?_some_table WHERE category = ?', $category); // $category может содержать любые символы

                                                                        Заметьте, примеры самые простые.

                                                                        p.s. По поводу
                                                                        > $result = $db->getRow('SELECT * FROM `table`');
                                                                        > на выходе получаем клёвый ассоциативный массив.

                                                                        Такие обертки легко пишутся вокруг функций mysql_*(), элементарно, и мне к ним возвращаться неохота, да и зачем тут PDO, это лишний слой абстракции.
                                                                          0
                                                                          >> $db->execute('INSERT INTO ?t (?#) VALUES (?a)', $table, array_keys($data), array_values($data));
                                                                          что мешает реализовать PDO::insert($table, $fields, $values)?

                                                                          клиентский код от этого только выйграет. не?

                                                                          и, ах да… озвучьте, пожалуйста, цели использования плейсхолдеров, тогда уж — складывается ощущение, что вы их используете только потому, что они есть в озвученной библиотеке. вы ведь понимаете, что в этом случае никаких нативных mysql средств не используется и всё скатывается до убогой симуляции настоящих нативных prepared запросов средствами языка программирования?
                                                                            0
                                                                            То, что придется реализовать update($table, $condition /* и как записывать condition? */, $data), delete(), кучу разных select()… вы представляете себе, какие сложные запросы бывают? Я сам пытался подобную штуку написать)) слишком много вариатов)

                                                                            И еще. По поводу плейсхолдеров. Если вы ими не пользуетесь, то либо вам приходится руками писать всюду real_string_escape(), что как вы понимаете лениво и ухудшает читабельность кода, либо вы их не пишете, и ваша программа — решето с инъекциями.

                                                                              0
                                                                              я представляю какие сложные запросы бывают. также — работаю с пдо уже не один год. мне ваши проблемы непонятны.

                                                                              по поводу решета — можете сходить попробовать поломать, к примеру, mzz.ru или тот же govnokod.ru ;-)

                                                                              ps: за сим дискуссию на пока ещё мирном тоне предлагаю закончить — и у вас и у меня просто привычка.

                                                                              спасибо за разговор! :-)
                                                                                0
                                                                                Ну ок тогда)) Я вообще на php чуть больше 2 лет программирую;) но тоже стараюсь пользоваться тем, что мне удобнее. И вам спасибо)

                                                                                p.s. То, что вы написали PDO::insert(), имхо лучше реализовтаь в модели (тогда параметр table из аргументов можно убрать, а Fields и values объединить в один ассоц. массив — типа Users::add($userprofile)), имхо библиотеке работы с БД, лучше работать с запросами, а вот модели — с данными (записями).
                                                                                  0
                                                                                  >> p.s. То, что вы написали PDO::insert(), имхо лучше реализовтаь в модели (тогда параметр table из аргументов можно убрать, а Fields и values объединить в один ассоц. массив — типа Users::add($userprofile)), имхо библиотеке работы с БД, лучше работать с запросами, а вот модели — с данными (записями).

                                                                                  совершенно верно — я хотел написать, что в нашем споре мы замешали вместе dbal и active record/table module, но перед отправкой эту часть сообщения стёр, посчитав слишком флеймообразующей :-)
                                                                                    0
                                                                                    pps: сам в работе предпочитаю более высокоуровневый DataMapper
                                                                                  0
                                                                                  скажи чесно, ты юзаешь pdo без обёртки? ксожалению, pdo не самодостаточен :(, но согласен, лучше надстраивать pdo, написаный на СИ, чем мараться с mysql_*.
                                                                                    0
                                                                                    mzzPdo и mzzPdoStatement можно посмотреть и скачать сам знаешь где :-)
                                                                                      0
                                                                                      ах да, непосредственно с пдо я имею дела не очень часто — вся работа с БД скрыта за орм. если интересно — реализацию смотреть всё там же :-)
                                                                                0
                                                                                $records = $db->getCell('SELECT COUNT(*) FROM ?_some_table WHERE category = ?', $category); // $category может содержать любые символы

                                                                                если вы боитесь написать 3 строки:
                                                                                1. prepare
                                                                                2. execure
                                                                                3. fetch
                                                                                — то у вас всегда есть возможность скрыть это за конкретным методом, который делает это всё.
                                                                                м?
                                                                                  0
                                                                                  Я не боюсь, я не вижу смысла писать 3 строки там, где можно обойтись одной;) Кроме того, у PDO всего 1 вид плейсхолдера, однозначно, мне этого недостаточно.

                                                                                  Зачем пытаться на PDO имитировать другую библиотеку, когда можно ей пользоваться?

                                                                                  И наконец, я не вижу смысла разделять prepare и execute, так как в 99% случаев я не вызываю один и тот же запрос в цикле, и никому не советую.

                                                                                  И еще. мы тут не затронули более сложные запросы, и ситуации, когда запрос формируется частями. Тут у SimpleDB есть удобная возможность засунуть опциональную часть запроса в такие скобочки {}

                                                                                  Имхо, PDO спроектирован кое-как.
                                                                                    0
                                                                                    >> Я не боюсь, я не вижу смысла писать 3 строки там, где можно обойтись одной;) Кроме того, у PDO всего 1 вид плейсхолдера, однозначно, мне этого недостаточно.
                                                                                    в библиотеке котерова примерно та же логика инкапсулирована в используемом вами методе. другое дело — что она уже реализована, а тут эти три строки придётся единожды написать и использовать лично вам.

                                                                                    >> Я не боюсь, я не вижу смысла писать 3 строки там, где можно обойтись одной;) Кроме того, у PDO всего 1 вид плейсхолдера, однозначно, мне этого недостаточно.
                                                                                    и не нужно. я к этому не призывал.

                                                                                    >> И еще. мы тут не затронули более сложные запросы, и ситуации, когда запрос формируется частями. Тут у SimpleDB есть удобная возможность засунуть опциональную часть запроса в такие скобочки {}
                                                                                    написал критерии, подобие критериев в пропеле — так что запросы формирую отдельной объектной моделью, которая (естественно) никакого отношения к dbal не имеет.

                                                                                    >> И наконец, я не вижу смысла разделять prepare и execute, так как в 99% случаев я не вызываю один и тот же запрос в цикле, и никому не советую.
                                                                                    и забываете одну из важных целей prepared'ов — предкомпиляция запросов на стороне сервера.
                                                                                      0
                                                                                      * во втором абзаце должна быть цитата
                                                                                      «Зачем пытаться на PDO имитировать другую библиотеку, когда можно ей пользоваться?»
                                                                                        0
                                                                                        Ох, почитал критерии в propel  — ад какой-то, сколько надо писать, вот не лень людям)) Я лично, когда продумывал форму записи условий, решил сделать проще: либо 1) ассоц. массив с AND-условиями (то есть в массиве набор полей и значений, объединенных AND), либо 2) в нумерованном массиве фрагмент условия с плейсхолдерами строкой и их значения. Преимущество — меньше писать, и более простой код (нет отдельного класса критериев, и кучи кода, а я не люблю тяжелые фреймворки), недостатки тоже наверно есть, но меня устраивает их соотношение.

                                                                                        То, что выше было про SimpleDB, это пример, я написал свою библиотечку по ее мотивам, из которой выкинул все что мне было не нужно;) и чуть-чуть расширив по своим вкусам.

                                                                                        Про прекомпиляцию слышыл только краем уха, работал с Mysql, а там с prepeared statements вроде как не очень.
                                                                                          0
                                                                                          Выше исключительно мое имхо, конечно надо писать на том, на чем тебе самому лучше пишется)) Ну и иногда посматривать на разные библиотеки, вдруг какую интересную идею можно подчерпнуть.
                                                                                            +1
                                                                                            критерии на редкость удобный инструмент. не ручаюсь за пропеловские — но реализованные мной явно удобные. иначе я (и ряд других людей) не пользовались бы ими в течение вот уже минимум пары лет :-)

                                                                                            govnokod.com/706

                                                                                            вот один из юнит тестов на генератор запросов.
                                                                                              0
                                                                                              Ох(( Я же написал, не люблю тяжелые библтиотеки, а в вашем примере одних только объектов и констант сколько, прям Zend framework какой-то. я когда-то думал насчет таких вариантов, но потом понял, что сложное условие (мне лично) будет проще написать именно в виде условия на SQL, а не набора вызовов addCondition(...) с кучей параметров. Ну и добавлять в строчке по одному условию мне лениво, так что я пожалуй останусь фанатом плейсхолдеров))

                                                                                              Вот еще вопросик был:

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

                                                                                              Цели: 1) экранирование нехороших символов (security first) 2) разнесение запроса и параметров этого запроса (читабельность) 3) ну и массивы удобно использовать, например «'Where id IN (?)', array(....)», и не надо писать кашу из кусков запроса, implode(), real_escape_string() и т.д. (ибо как я писал уже, я не люблю писать много кода, пальцы устанут)

                                                                                              Имитировать prepared-statements цели не было))
                                                                                                0
                                                                                                зато процесс генерации запросов очень упрощается — объект критерии можно свободно передавать между объектами, каждый из которых в него будет добавлять что-то своё.
                                                                                              0
                                                                                              Только не SimpleDB, а DbSimple. :-)

                                                                                              А насчет синтаксиса Propel (и вообще ORM) — то на первый взгляд и правда кажется, что он очень громоздкий. Но на практике эта громоздкость, что удивительно, почти совсем не мешает. А вот много проблем с тем, что Propel (и другие ORM) способствуют неконтролируемому росту кол-ва разновидностей («планов») SQL-запросов, и оптимизировать такой код впоследствии становится очень сложным. SQL оказывается ровным слоем размазанным по всему приложению. Впрочем, та же проблема и с ручной генерацией SQL через тот же DbSimple или PDO. Локализовывать нужно SQL, ох локализовывать…
                                                                                                0
                                                                                                Я все время путаю название и на амазоновский сервис натыкаюсь))

                                                                                                Ну а синтаксис для меня важен, я печатаю не очень, да и просто объемистый код не люблю. А локализовать SQL проще всего, заперев его в моделях))
                                                                                    0
                                                                                    pps: вышеприведённый запрос используется так:

                                                                                      0
                                                                                      $result = $db->getRow('SELECT * FROM `table`');

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

                                                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                            Самое читаемое