sol Posted January 30, 2016 1. PHP я знаю плохо. 2. Учить PHP не хочу. 3. perl знаю хорошо. 4. Есть большое веб приложение на PHP, в котором имеется примерно следующий код в процессе инициализации: $speeds = array (); $q='select id,name,speed from tk_tariff'; $r=mysql_query($q,$db); while ($p=mysql_fetch_array($r)) { $speeds[$p[0]]=$p[2]; } Далее по тексту используется $speeds Проект отлажен (не мной) и работает. 5. Я не хочу делать ф-цию get_tariff_speed_by_id() и менять по объёмному тексту все вхождения $speeds на вызов get_tariff_speed_by_id() 6. В перле есть "связывание" tie. Я могу связать переменную с некоторой структурой навроде объекта, которая будет перехватывать чтение и запись переменной и, вместо чтения или записи, выполнять какие-то свои методы/функции. Например, в моём случае, делать селекты в базу по мере нужды а не выбирать всю таблицу разом. Внимание вопрос: Есть ли аналогичный механизм в PHP? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
terrible Posted January 30, 2016 $a='Some Text<br />'; $b=$a; //присваивание значения $a='Bla Bla Bla<br />'; echo $b; //значение: Some Text $c=& $a; //ссылка на переменную $a='PHP Use<br />'; echo $c; //значение: PHP Use Оно? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
sol Posted January 30, 2016 Не оно. Надо, чтобы при вызове $s = $speed[38] происходит вызов некоей ф-ции, которая делала бы select speed from tk_tariffs where id=38 return $s; Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
terrible Posted January 30, 2016 Вот это похоже: http://php.net/manual/ru/functions.variable-functions.php Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
sol Posted January 30, 2016 Опять не то... https://www.opennet....rl_tie.txt.html Вот то, что надо. Для перла, мне надо описать методы TIEHASH classname, LIST FETCH this, key STORE this, key, value DELETE this, key CLEAR this EXISTS this, key FIRSTKEY this NEXTKEY this, lastkey SCALAR this DESTROY this UNTIE this и "связать" этот класс (объект) с хешем (переменной типа "ассоциативный массив"). Все эти методы писать с нуля не надо, есть стандартный класс Tie::StdHash, от которого надо унаследовать новый класс и, в моём случае, написать методы №2 и №3 и, возможно №6. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Wingman Posted January 30, 2016 Могу ошибаться, но, боюсь, нет такого в функциональном php. Только в ООП из похожего есть магические __call(), которые могут перехватывать вызов любой переменной, но только в рамках класса. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
alibek Posted February 2, 2016 Если речь про БД, то есть mysqli_stmt::bind_param/mysqli_stmt::bind_result (для MySQLi) и PDOStatement::bindParam/PDOStatement::bindColumn (для PDO). Но вообще это разные языки. Один и тот же подход получиться использовать не везде. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
sol Posted February 2, 2016 Да нет -же! Беда в том, что автор извлекает табличку в массив сразу и целиком. И в дальнейшем работает только с этим массивом. Во многих частях этого проекта выбирая из него по 1-2 значения. При этом в начале не известно, нужны ли вообще будут данные из этой таблицы. Табличка не маленькая, народу в апликухе сидит много, табличку эту дёргают. При некоторых обстоятельствах разом запросов 80 висит. Мне это не нравится. Я хотел без существенного рефакторинга самого проекта сделать финт, который сделал бы не задумываясь на перле. Сделал бы "магическую" переменную, обращения к которой перехватывались бы функциями. В перле это запросто. Я думал, что и в php не трудно. А оказалось - показалось... Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
alibek Posted February 2, 2016 Тогда переменную превратить в объект и использовать магические методы. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Wingman Posted February 2, 2016 Гхм... Если запрос реально НАСТОЛЬКО простой: $q='select id,name,speed from tk_tariff'; и если его результат неизменен, и если вас беспокоит скорость его выполнения и висящие запросы - просто используйте, например, memcached для кеширования. В месте, где этот запрос выполняется, сначала дёргайте кеш, и только если в кеше массива нет - дёргайте базу. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
sol Posted February 3, 2016 Тогда переменную превратить в объект и использовать магические методы. Где про это прочесть?Гхм... Если запрос реально НАСТОЛЬКО простой: Это копипаста из проекта... и если его результат неизменен Меняется, но очень редко. Одно изменение на 10-20к запросов. И это верхняя граница. В реальности, меняется реже. memcached - это оверкилл. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Wingman Posted February 3, 2016 memcached - это оверкилл. Однако он предназначен именно для кеширования часто запрашиваемых, но редко меняющихся данных. Как раз ваш случай, имхо. Пихать в кеш на 10-15 минут - и всё было бы замечательно. Оверкиллом оно было бы, если бы приходилось мастрячить что-то монструозное, тяжелое и требующее много времени на внедрение. А тут - легковесный демон, даже настройки не требующий. Тогда переменную превратить в объект и использовать магические методы. Где про это прочесть? Да не получится ничего без изменения кода во всех местах вызова этого массива. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
sol Posted February 5, 2016 Ну нет же! Вместо того, чтобы почти контекстной заменой поменять $s = $speed[38] на $s = get_this_***ing_speed(38) предлагается городить целого демона и всё одно переписывать код. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
alibek Posted February 5, 2016 предлагается городить целого демона Тут есть нюанс. В исходном варианте в $speeds загружается вся таблица при каждом http-запросе. Если ее заменить на функцию, то будет загружаться не вся таблица, а только отдельные строки. Но тоже при каждом http-запросе. А memcached позволит сделать так, чтобы строки из таблицы загружались только при перезапуске сервера, между http-запросами обращения к БД не потребуются. Так что совет про memcached в целом неплохой. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Wingman Posted February 5, 2016 Всё так, только чуть дополню: - "строки из таблицы загружались только при перезапуске сервера" - класть в кеш лучше таки с таймаутом: минут на 10-15. Соответственно, и актуальность данных будет с лагом 10-15 минут. - "и всё одно переписывать код." - При замене массива на вызов функции - код меняется в куче мест, при использовании кеша - только в одном. А так - дело ваше, конечно :) Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...