За последние 24 часа нас посетили 22834 программиста и 1246 роботов. Сейчас ищут 752 программиста ...

ORM

Тема в разделе "Решения, алгоритмы", создана пользователем Ti, 29 апр 2009.

  1. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    Тихо и незаметно вышла ORMv2.1 (90kb)
    changelog:
    + поддержка MySQL
    + привязка к произвольной структуре db
    + метод ORM::Get() возращающий коллекцию классов
    + подстановка в IDE свойств объкта и ORM_List
    - many-to-may
     
  2. Frozen

    Frozen Активный пользователь

    С нами с:
    20 окт 2008
    Сообщения:
    540
    Симпатии:
    0
    Адрес:
    Москва
    Fatal error: Method ORM_Condition_Property::__toString() must not throw an exception in
     
  3. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    oO как сделал?
     
  4. Frozen

    Frozen Активный пользователь

    С нами с:
    20 окт 2008
    Сообщения:
    540
    Симпатии:
    0
    Адрес:
    Москва
    а как вообще начать работать с существующими таблицами? Как убрать префикс?

    накидай примерчиков плз :)
     
  5. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    PHP:
    1. <?
    2. require_once 'bootstrap.php';
    3.  
    4. header('Content-Type: text/html; charset=utf-8');
    5.  
    6. $scheme = ORM_Scheme::GetInstance();
    7.  
    8. // setup.php
    9. if (!$scheme->exists('User')) { // импортируем схему из базы
    10.     $class = $scheme->bind('User', 'my_table_user');
    11.     $class->bindAllFromDb();
    12.    
    13.     $class = $scheme->bind('Phone', 'my_table_phone');
    14.     $class->bindAllFromDb();
    15.     // отвязываем свойство user_id
    16.     // привязываем свойство user (my_table_phone.user_id) к классу User
    17.     $class->unbind('user_id')->bind('user', 'user_id', 'User');
    18.  
    19.     $scheme->save();
    20.    
    21.     // фалшивые-классы (для автоподстановки в IDE). Не подключайте этот файл!
    22.     file_put_contents(dirname(__FILE__).'/fake.php', '<'."?\n".ORM_Scheme_Export_Php::Export());
    23. }
    24.  
    25. $user = ORM()->User();
    26. $user->name = 'myName';
    27. $user->save();
    28.  
    29. $phone = ORM()->Phone();
    30. $phone->number = '512311';
    31. $phone->user = $user;
    32. $phone->save();
    33.  
    34.  
    35.  
    36. // небольшое how-to:
    37.  
    38. // объект ORM_Object представляют из себя записи:
    39. // Добавление записи
    40. $category = ORM()->Shop_Category();
    41. $category->title = 'waka';
    42. $category->save();
    43.  
    44. // Удаление
    45. $category->delete();
    46.  
    47. // Изменение
    48. $category->title = 'new title';
    49. $category->save();
    50.  
    51. // Для получения записи используется ORM_List
    52.  
    53.  
    54. // коллекция ORM_List объектов
    55. $collect = ORM();
    56.  
    57.  
    58. // получение объекта ORM_List
    59. $categoryList = $collect->Shop_Category; // ORM_List (спиок Shop_Category)
    60.  
    61.  
    62. // объекты ORM_List управляют выборкой из базы:
    63. // WHERE
    64. $categoryList->title = 'test';              // WHERE title = 'test'
    65. $categoryList->equals('title', 'test');     // ... AND title = 'test'
    66. $categoryList->notEquals('title', 'wtf?');  // ... AND title != 'wtf?'
    67. $categoryList->isNull('title');             // ... AND ISNULL(title)
    68. $categoryList->isNotNull('title');          // ... AND NOT ISNULL(title)
    69. $categoryList->addSymbol('id', '<', 10);    // ... AND id < 10
    70. $categoryList->inArray('id', array(1,3,5)); // ... AND id IN (1,3,5)
    71. $categoryList->like('title', '%waka');      // ... AND title LIKE '%waka'
    72.  
    73. // ORDER BY
    74. $categoryList->addOrder('title');           // ORDER BY title
    75. $categoryList->addOrder('id', false);       // ..., id DESC
    76. $categoryList->addOrderRandom();            // ..., RAND();
    77.  
    78. // LIMIT
    79. $categoryList->setLimit(5);                 // LIMIT 5
    80. $categoryList->setOffset(10);               // OFFSET 10
    81.  
    82. $count = $categoryList->count();            // колличество записей без учета LIMIT и OFFSET (SELECT COUNT(*) FROM ... WHERE ...)
    83. $count = count($categoryList);              // или так
    84. $count = $categoryList->countInResult();    // колличество записей в результате (mysql_num_rows)
    85.  
    86. echo $categoryList->getQueryBuilder()->getSelect(); // посмотреть какой запрос будет выполнен
    87.  
    88. foreach ($categoryList as $cagegory) {
    89.     // $category instanceof ORM_Object === true
    90.     // ...
    91. }
    92.  
    93. // получение первой записи
    94. $category = $categoryList->getOne();        //
    95.  
    96.  
    97. // получение записи по ID
    98. $category = $collect->Shop_Category(5);
    99. echo $category->id; // 5
    100.  
    101.  
    102. // некоторые свойства объектов - ORM_Object
    103. $parentCategory = $category->parent;
    104. $parentParentCategory = $parentCategory->parent;
    105.  
    106.  
    107. //
    108. $title = ORM::Get()->Shop_Category
    109.     ->equals('title', 'waka')
    110.     ->inArray('id', array(123, 2, 3))
    111.  
    112.     ->setLimit(5)
    113.     ->addOrder('title', false)
    114.  
    115.     ->getOne()
    116.  
    117.     ->title;
    118.  
     
  6. dvloper

    dvloper Активный пользователь

    С нами с:
    30 июн 2009
    Сообщения:
    3
    Симпатии:
    0
    А что не устраивает в готовых PHP framework с ORM?
    Есть же CodeIgniter, Kohana, ActiveRecord и т.д.
    Я тоже пытаюсь сделать нечто подобное ORM на PHP. Но меня не устраивает в существующих фреймворках отсутствие необходимого для меня комплекса: ORM+"кроссбазность"+MVC+набор Helpers. Кроме того, мне хотелось бы видеть описание модели данных аналогично EJB3 для J2EE. Из всех фреймворков более-менее моим запросам удовлетворяют CodeIgniter, Kohana и EzPDo, но в каждом чего-то да не хватает.
    CodeIgniter сделан в стиле PHP4. Kohana - в последних версиях не совсем кроссбазная. В EzPDO есть только ORM без MVC, зато там модель задается так как мне надо. Вот пытаюсь наваять что-то сам, только кривовато выходит. Могу обменяться опытом, если надо.
     
  7. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    dvloper
    Когда ваш запрос превратится в нечто монструозное или логически сложное - о кроссбазности говорить не придётся, потому что в разных базах придётся писать разные запросы. Давно пора это понять.
     
  8. dvloper

    dvloper Активный пользователь

    С нами с:
    30 июн 2009
    Сообщения:
    3
    Симпатии:
    0
    Не разделяю этой точки зрения, именно потому как пришлось немало поделать таких монструозных запросов на разных базах. В итоге пришел к выводу, что подобные запросы возникают когда плохо продумана бизнес-логика проекта.
    В классической трехзвенке бизнес-логику можно сделать либо в базе, либо в сервере приложений.
    Первый вариант не требует от сервера приложений "монструозных" запросов, но накрывается медным тазом, когда к вам приходит заказчик и говорит: "Хочу тоже самое но на сервере XX (Oracle, MSSQL и т.д)"
    Второй вариант при нормально реализованной ORM вообще не должен по идее требовать SQL: пример - EJB в Java. Взаимодействие с базой (внутри ORM) строится простейшими запросами самыми сложными из которых - это джойны. Т.е. логика делается не с помощью SQL, а с помощью другого языка.
    Монструозность запросов - это прямое следствие того, что SQL предназначен только для работы с РЕЛЯЦИОННЫМ представлением данных. В реальности же приходится работать с бизнес-объектами, которые суть ОБЪЕКТНОЕ представление данных. Давно пора это понять.
     
  9. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    Мои пожелания к ORM написаны в первом посту

    А зачем MVC привязывать к ORM
     
  10. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    dvloper
    Видел я такие списки сложных данных - на страницу 500-600 запросов, потому что по другому в бизнес приложении вобщем-то сделать трудно, хотя были варианты оптимизаций, но слишком трудоёмкие и всёравно запросов оставалось штук 100 при 40 записях на страницу. С системой работало 5-6 операторов и был куплен мощный сервер. Для сайта был сделан лёгкий сайт с синхронизацией баз из основной системы для облегчения самой базы и позволить серверу быстро работать с ней.

    Теперь возмите соц. сеть. Запрос, который длится больше 0.2-0.3 впринципе тормоз и его нужно оптимизировать. Не получается? Кешировать, писать демоны - неважно как - это надо сделать. На голом ANSI SQL этого не сделать, а ваш пресловутый ORM скорее всего наделает кучу запросов вместо одного. В WEB сайте важна латентность и скорость загрузки. ORM может сделать такой запрос?
    [SQL]SELECT SQL_CALC_FOUND_ROWS
    tg.id, tg.category_id, tg.numratings, tg.ratingsum, DATE_FORMAT(tg.last_changes, "%Y-%m-%d %H:%i:%s") AS tg_last_changes,
    IF(tg.last_changes > NOW() - INTERVAL 1 DAY, 1, 0) AS is_new, tgt.name AS tgt_name, c.image, c.activity,
    ct.name AS ct_name, tic.cnt AS torr_cnt, tic.comm_sum AS comm_sum, tic.leechers AS leechers, tic.seeders AS seeders,
    tic.downloaded AS downloaded, tg.original_name, tic.year,
    CONCAT(IFNULL(tg.genre, ""), IFNULL(tg.genre2, ""), IFNULL(tg.genre3, "")) AS genre,
    tic.season_part, tic.producer
    FROM torr_groups tg
    JOIN torr_groups_trans tgt ON tgt.id=tg.id AND tgt.lang_code="rus"
    JOIN categories c ON c.id=tg.category_id
    JOIN categories_trans ct ON ct.id=c.id AND ct.lang_code="rus"
    LEFT JOIN (
    SELECT
    ti.torr_group_id,
    count(*) as cnt,
    sum(ti.comments) as comm_sum,
    SUM(ti.seeders) AS seeders,
    SUM(ti.leechers) AS leechers,
    SUM(ti.downloaded) AS downloaded,
    ti.year,
    ti.season_part,
    tt.producer
    FROM torr_info AS ti
    LEFT JOIN torr_trans AS tt ON tt.id = ti.id AND tt.lang_code="rus"
    WHERE ti.visible="yes"
    GROUP BY ti.torr_group_id
    ) tic ON tic.torr_group_id=tg.id
    WHERE tic.cnt > 0
    ORDER BY tg.last_changes desc
    LIMIT 0, 30;[/SQL]
     
  11. dvloper

    dvloper Активный пользователь

    С нами с:
    30 июн 2009
    Сообщения:
    3
    Симпатии:
    0
    Я ему про фому, а он про ерему :)
    1. Не надо меряться "крутизной". Повторюсь - мне приходилось писать запросы для сложных приложений. Как вам хранимая процедура килов на 30 голого SQL? Или запросы на выборку отчетов тоже килов на 10 со всеми прелестями: join'ами, union' ами, группировками и сортировками? Естественно все писалось и оптимизировалось под конкретную БД руками, без всяких билдеров. Так что если хотите показать свою крутость - лучше на ком-нибудь другом.
    2. Я пытаюсь донести простую вещь: во всех нормальных языках программирования уже давно есть средства по отвязыванию бизнес-логики от SQL, а значит и от вида сервера БД. Мне нужна такая же вещь в PHP. Почему кросс-базная? Потому что возможна перспектива дальнейшего переноса приложений с хостинга на сервера разных клиентов у которых и запросы к БД могут быть разные. Есть ли такая возможность в существующих фреймворках - другой вопрос. Потому и говорю, что приходится кропать что-то свое.
    2. По поводу кучи запросов от ORM - если нормально сделать ORM, может кучи запросов и не потребуется. Кроме того, суть не в запросах, а в том, чтобы бизнес-логику можно было нормально делать в PHP а не SQL.
    3. Быстродействие выборки данных - это всего лишь вопрос цены за сервер. Если вы делаете Web-приложение социальной сети на виртуальном а не выделенном сервере - флаг вам в руки, экономьте, но как бы не оптимизировались запросы, сервак рано или поздно у вас не выдержит, т.к. не одни вы на нем висите. А на выделенном сервере при нынешнем железе я не вижу проблем с быстродействием.
    4. По поводу примера: а нужен вообще такой запрос ?(кстати не очень он уж и "монстерский"). Может вы неправильно сделали отношения между сущностями в БД, что вам такой запрос требуется? Или может надо добавить пару лишних полей, вовремя их апдейтить и тогда и суммирование в подзапросе не потребуется? Это я к тому, что БД обычно разрабатываются "в лоб". Взяли накидали табличек, а потом думают, как из оного что-то SQL-ем вытащить. Про то надо оно с точки зрения бизнес-модели или нет обычно не думают, вот вам и "монстерские" запросы. Был у меня случай: в системе страшно тормозил модуль работы с курсами валют. Оказывается от большого ума какой-то умник вставил подзапрос на выборку текущего курса в главном запросе: [sql]select Rate from Rates order by CurDate desc[/sql]. А стоило добавить поле текущего курса в таблицу типов валют с обновлением его 1 раз в день и вуаля! Вместо подзапроса обычный join и модуль стал просто летать! Вобщем, принцип KISS рулит всегда.
     
  12. kostyl

    kostyl Guest

    Это и не было связано никогда.
    мало смотрел наверно
    может ты не понял, что этот запрос делает?
    ps: прошу прощения за такой пафос
     
  13. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.255
    Симпатии:
    0
    Адрес:
    Київ
    Вообще я отчасти согласен с dvloper, сам недавно такой запрос рефакторил.
    имхо, все же "comments", "seeders", "leechers", "downloaded" стоило денормализовать. Как говорил один мой знакомый Джава-прогер, опытный хайлоадщик: "Джоины работают быстро, пока ты их не заставляешь считать". Что-то типа такого.
     
  14. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    dvloper
    Теоретически - да, можно было сделать поля, в которых тот JOIN (SELECT ...) кешировался. Однако, т.к. вы не знакомы с работой трекера, вы такой оптимизацией скорее просто убъёте его нагрузкой.
    Фишка в том, что seeders, leechers, downloads это статистика по каждому конкретному торренту. А торренты собраны в группы, список которых этот запрос и показывает. По торрентам вытаскивается общая для них инфа как название, год и.т.д. А теперь представте кол-во update запросов, которые будут вызывать такие простейшие вещи как добавление пира, переход из личера в сидеры? При скачке торрент файла. Если сейчас у меня ~450 queries/sec, то оно резко подскочит где-то до 650-700 штук в секунду. Я и так из-за слишком большого кол-ва UPDATE/INSERT запросов использую DELAYED режим для UPDATE/INSERT, иначе сервер просто не успевает нормально делать селекты и выкрученные буфера вставки данных. Денормализация более-менее сделана, иначе здесь бы было ещё как минимум 3-4 суб селекта. Вообще всё это хорошо работает по той простой причине, что таблица пиров сделана Memory, потому что InnoDB просто плохо справлялось c 50% на 50% read/write при 90% запросов идущих к ней.

    Да, сама система может быть немного переделана, это и планируется в ближайший месяц-два сделать - будет легче выбирать данные. Но таблицы с переводами в любом случае останутся, т.к. на сайте 3 языка, да и статистика по кол-ву сидеров и личеров, скачек всёравно будет выбираться live - она слишком быстро меняется, а делать прекалькулированные поля на таблицу, которая постоянно читается только добавлять дополнительный bottleneck. Можно сделать обновление раз в Х минут, что вариант. Но это нужно ещё исследовать и проверять. Потом доделывать кеширование и.т.д.

    Так что в реальности не всё так просто как кажется - пихнул ORM и всё гут. ORM при правильном использовании это не плохо, но смысл оно имеет только на большом проекте. В маленьком это пушка, паляшая по воробъям и на каком-нить VDS добавляющая жуткий Overhead. Добавте ещё Smarty в комплект, и вообще будет весело - ему даже bytecode cacher's сильно не помогают. Точнее помогают - дают прирост в 2.5 раза где-то. Только native шаблонизатор простейший тупо работает раз в 30-40 быстрее и без кешеров (на хабре пару недель назад было об этом).

    А ещё ORM как правило делают Active Record, что сказывается на memory usage, иногда, знаете ли, весьма существенный пункт. Добавить лишний гиг рама одному серверу - фигня. А когда у тебя 5-6 серверов, требующих буфферизированную DDR2 ECC память, которая стоит так, что 10 раз подумаешь что дешевле - заставить программиста месяц оптимизировать или докупить памяти на 2 его зарплаты?

    Что до процедур - каюсь, я их особо не делал. Но видел процедуры по 2.5-4к строчек SQL кода. Биллинговая система учёта трафика у магистрального Internet провайдера - я представляю что это такое. Все мы так или иначе пуганы.

    Что до примера с курсом валют - надо было не subselect ставить, а derived query сделать, если надо было live - курс теоретически может и чаще менятся чем раз в сутки :)

    Что до бизнес-логики - вы, батенька, спуститесь до уровня PHP сперва :) Какая бизнес логика, какие ORM? Мы тут пишем кашу из PHP, HTML и CSS, а вы нас бизнес-логикой пугаете. Ирония? Да, но с долей истины. PHP из-за своей направленности и особенностей не приспособлен для разработки сверх-тяжелых приложений с использованием множества тяжелых библиотек - это медленно работает. Это не Java, не C++ - это надо понять раз и на всегда. К тому-же, как я считаю, конструкции вида:
    PHP:
    1. <?php
    2. $orm->select('table')->addFields(array('field1', 'field2', 'SUM(field3)')->where(array('field4' => 4)->order_by('field5 DESC')->limit(0, 20);
    3.  
    Куда более не понятны при любом, более-менее многострочном запросе, чем сам запрос. Не говоря уже об издержках на создание запроса таким манером. Возьму Doctrine и потестирую как-нить, посмотрим что из этого выйдет. На крайняк есть PDO - используйте.

    TheShock
    Джойны плохо работают, когда таблицы за большие становятся, а cardinality индексов мала - тогда иногда проще сделать не через JOIN, а через SELECT FROM (SELECT FROM ) - так кстати работают с MySQL NDB Cluster, т.к. из-за его особенностей JOIN'ы по большей части там обсалютно не юзабельны из-за необходимости слияния таблиц. А лучше всего простые запросы на одну таблицу, особенно по primary key (IN() в этом смысле крайне крут).
     
  15. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    В настоящий момент ORM v3 не разрабатываю т.к. много работы и других не менее интересных проектов
    Желание на пропало, не остыло и обязательно будет оформлено в виде кода.

    между тем, подросла ветка v2:
    - небольшие багофиксы
    - добавлена функция ORM()

    использование функции ORM()
    PHP:
    1. <?
    2. // 1. Создание объекта (эквивалент new Phone)
    3. $phone = ORM()->Phone();
    4. $phone->number = '+7 (222) 222-22-22';
    5. $phone->save();
    6.  
    7. // удобно для разименования:
    8. ORM()->Phone()->set('numer', '+7 (333) 333-33-33')->save();
    9.  
    10.  
    11. // 2. Получение по ID
    12. $phoneId5 = ORM()->Phone(5);
    13.  
    14. // или так:
    15. $phoneId6 = ORM('Phone', 6)
    16.  
    17.  
    18. // 3. Спискок
    19. $phoneList = ORM()->Phone;
    20. foreach($phoneList as $phone) echo $phone->number;
    21.  
    22. // или так:
    23. $phoneList = ORM('Phone');
    24. foreach($phoneList as $phone) echo $phone->number;
    25.  
    скачать ORM v2.2

    Enjoy!


    P.S.
    Для автоподстановки в IDE генерируется специальный фейк-файл.
    Благодаря этому тот же Zend Studio 7 знает какого типа находится объект внутри foreach без дополнительного phpdoc комментария @var:
    PHP:
    1. <?php
    2. foreach(ORM()->Phone as $phone) {
    3.    echo $phone->user->name;
    4. }
    user и name в данном случае будет ctrl-кликабельный.
    Но ZDE не предоставляет автоподстановку в этом случае что добавляет неудобства в разработке и решается лишь phpdoc комментарием.
     
  16. r00les

    r00les Активный пользователь

    С нами с:
    4 сен 2009
    Сообщения:
    142
    Симпатии:
    0
    А чем вам не нравятся SQL запросы в чистом виде, ну ещё канешь написать небольшой класс который от инъекций обезопасит ну и данные вернёт в объекте, а так к чему эти санки когда лето на дворе ?
     
  17. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    r00les
    Реализуя крупные проекты без ООП — как плавать в океане на надувном матрасе.
    ORM — это «небольшой класс который от инъекций обезопасит ну и данные вернёт в объекте», над которым провели декомпозицию и немного расширили функционал.
     
  18. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    в хотелки:
    PHP:
    1.  
    2. <?php
    3. // SQL: INSERT INTO user(nick, icq) VALUES('Ti', '177717007')
    4. ORM()->User[] = array('nick'=>'Ti', 'icq'=>'177717007');
    5.  
    6. // SQL: UPDATE user SET phone = '1111' WHERE id = 1
    7. ORM()->User[1] = array('phone'=>111);
    8. // или:
    9. ORM()->User[1]['phone'] = 111;
    10.  
    11. // SQL: DELETE FROM user WHERE id = 1
    12. unset(ORM()->User[1]);
     
  19. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    такое если я правильно помню работать не будет. А будет ругаться нотисами про непрямое изменение перегруженного свойства.

    И остальное тоже, если предварительно элементы не были установлены.

    Для того чтобы это работало тебе придется реализовывать User с интерфейсом ArrayAccess
    а для такого
    И каждое свойство делать объектом с интерфейсом ArrayAccess
     
  20. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    PHP:
    1.  <?php
    2. mysql_query("INSERT INTO log (id,text) VALUES(NULL,'В жопу ОРМ=)')");
    Ti
    я понял почему мне так не нравятся обёртки - неочевидностью выполняемого дейтсвия
     
  21. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    а мой контроллер значит заплевал да? )
     
  22. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    User уже имеет реализацию ArrayAccess и User['phone'] = '123' уже работает.
    Пока не работает ORM()->User[$id] - ибо ORM()->User - возращает не класс User а итератор этого класса, у которого пока не реализован ArrayAccess.

    Каждое свойство не нужно делать ArrayAccess.
    Конечно, если свойство является объектом ORM он имеет ту же самую реализацию.


    Mr.M.I.T.
    ты неправильный эквивалент подобрал. Твой "очевидный" вариант должен выглядеть по меньшей мере так:
    PHP:
    1. <?php
    2. $text = mysql_escape_string("В жопу ОРМ=)");
    3. $result = mysql_query("INSERT INTO log (id,text) VALUES(NULL,'$text')");
    4. if ($result) trigger_error("Fail: ".mysql_error());
    И чем это удобней, понятней, безопасней и очевидней ORM?
    PHP:
    1. <?php
    2. ORM()->log[] = array('text'=>'В жопу голый SQL');
     
  23. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    А код ниже?
     
  24. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    всем. мне не нужно учить чужой голимый API. я работаю напрямую с php'ным апи ядра.
    те кого пугают всякие "обезопаснивания" юзают плейсхолдеры и простенькие обёртки
    PHP:
    1.  
    2. <?
    3. DB::Query("INSERT INTO log (id,text) VALUES(NULL,'?')","В жопу ОРМ =)");
    4. DB::Insert("log",array("text"=>"В жопу его"));
    5. ?>
     
  25. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    Очевидный API учить не надо