Поиск по сайту:
taxpert.ruБлог — Шпаргалка по трюкам в PHP и MySQL

Шпаргалка по трюкам в PHP и MySQL

30.09.2020

Секция: Сайтостроение и WEB-разработка

Просмотров: 488

Комментариев нет — ваш комментарий может стать первым

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

Модификация значения внешних переменных из функции array_map. Когда есть некая переменная, которую мы определили за пределами функции array_map, то импорт её значения внутрь функции осуществляется с помощью оператора use:

implode(" а также ",array_map(function($amk,$amv)use($data){…

А вот как не только импортировать значение внешней переменной, но и модифицировать его, в том смысле, чтобы значение этой переменой изменялось не только фнутри функции, но и снаружи? А элементарно: в качестве аргумента ставим у use ссылку на переменную, указывая для этого апостроф перед именем нужной нам переменной:

implode(" а также ",array_map(function($amk,$amv)use(&$data){…

…и порядок: теперь каждое изменение переменной внутри функции будет изменять её значение и снаружи.

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

array_walk_recursive ($myarray,function(&$value,$key) { $value = str_replace(array(chr(39),chr(92)),NULL,$value); });

Данная конструкция рекурсивно перебирает все элементы многомерного массива $myarray и передаёт управление анонимной функции, которая исключает из каждого входящего значения символы с кодом 39 (апостроф) и 92 (слэш). Первый аргумент ($value) передаётся в анонимную функцию по ссылке, что позволяет функции модифицировать значения непосредственно в массиве $myarray, а не только во входящем локальном значении.

Использование анонимной callback-функции. Зачем это нужно? Ну, например, у вас есть массив значений, и вам необходимо всунуть его в условие IN в MySQL-запросе (типа «...WHERE city IN ("novosibirsk","saratov","samara")»). Проблема в том, что в массиве значения «голые», а в условии IN они должны быть каждое в кавычках, да ещё и обёрнутые в скобки. Конечно, можно воспользоваться конструкцией FOREACH с целью последовательного перебора элементов массива, но зачем, если можно обойтись всего одной строкой?

$city_condition = '('.implode(chr(44),array_map(function($x){return(chr(34).$x.chr(34));},$city_condition)).')';

Что здесь зачем?

$city_condition — это массив типа array("novosibirsk","saratov","samara"). Оператор ARRAY_MAP производит операцию над каждым из элементов массива $city_condition, в данном случае — оборачивает их в кавычки с помощью анонимной callback-функции (поочерёдно передавая их анонимной функции через параметр $x, который в принципе мог бы называться как угодно иначе, лишь бы был единственным при передаче в функцию). Ну а оператор IMPLODE складывает полученный у оператора ARRAY_MAP массив значений, уже обёрнутых в кавычки, в текстовую строку с разделителем в виде запятой. Результат этого выражения передаётся обратно в массив $city_condition, который после передачи результат превращается в текстовую строку нужного нам формата. И нам с вами остаётся лишь добавить сформированное условие в запрос: «WHERE city IN '.$city_condition».

Передача дополнительных параметров в анонимную callback-функцию. Иногда возникает необходимость передать в анонимную callback-функцию (вроде той, что упоминалась выше) значение каких-либо переменных, видимых там, откуда запускается функция, но не видимых внутри самой функции. Использовать global, массив $GLOBALS или объявлять константу всего лишь для того, чтобы через пару строк анонимная функция получила нужные ей значения — как-то несерьёзно, а передать их в числе аргументов не получится — как уже говорилось выше, в качестве аргумента в анонимную callback-функцию передаётся строго один аргумент. Что же делать?

Решение в этом случае очень простое — использовать ключевое слово USE:

$city_condition = '('.implode(chr(44),array_map(function($x) use ($city_list) {return(chr(34).$x.chr(34));},$city_condition)).')';

Передача массива с ключами в анонимную callback-функцию. Довольно каверзная задача, с которой пришлось как-то столкнуться: ну не хочет функция array_map передавать сразу и ключ и значение элемента в анонимную функцию. Если, конечно не пользоваться следующей конструкцией:

array_map(function($key,$value) { return('key = '.$key.' value = '.$value); },array_keys($my_own_array),$my_own_array);

Назначение нескольким переменным одного и того же значения. Нет, понятно, что назначить трём переменным одно и то же значение — это всего-навсего три строки, но почему бы не сжать до одной-единственной?

$my_city = $main_city = $central_city = 'moscow';

Определение, подключена ли библиотека оператором required. Такого оператора в PHP нет, но зато есть операторы function_exists (определена ли функция?) и is_defined (определена ли константа?). Обычно просто проверяю, определена ли первая либо ключевая функция из библиотеки, подключение которой проверяется. Если нет — значит, не подключена. А если намеренно совать в библиотеки определение констант типа MYSQL_LIBRARY_CONNECTED — жизнь станет ещё прекраснее.

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

if($value=='tambov' || $value=='rostov' || $value=='sochi')

...гораздо проще (и нагляднее) написать:

if(in_array($value,array('tambov','rostov','sochi')))

Текстовый редактор запуском одной-единственной строки. Вообще ни разу не PHP, но лайфхак настолько простой и немыслимо, невероятно удобный, что я решил включить его сюда. Просто налей воды вставляете в адресную строку браузера следующий текст: data:text/html,, и окно браузера превращается в простой текстовый редактор. Сочетание клавиш Ctrl+I и Ctrl+B способно творить чудеса превращать текст в курсив или жирный шрифт. При желании же можно немного расширить функционал: превращать в текстовый редактор не всю страницу, а отдельный контейнер, добавив в него тег contenteditable и задав для него стили точно так же, как для любого другого обычного HTML-элемента. Ну а если ещё и подвязать к странице с редактируемемым контейнером код, с периодичностью в пару секунд отправляющий POST-запрос с содержимым контейнера PHP-сценарию — можно сделать автосохранение текста контейнера на сервере.

Вывод множества результатов подзапроса MySQL без ошибки. Если вам доводилось вставлять в запрос MySQL подзапросы, то вы, вероятно, сталкивались с ошибкой, когда получали в ответ сообщение "Подзапрос возвращает более одной записи". Так вот, данная проблема решается при помощи оператора GROUP_CONCAT, который при получении более 1 строки из подзапроса объединяет полученные значения с использованием разделителя так же, как это делает с массивом оператор IMPLODE. Конструкция выглядит следующим образом: SELECT unikey AS unik,(SELECT GROUP_CONCAT(member_id ORDER BY member_id SEPARATOR ',') FROM member_table WHERE outkey=unik) AS members FROM documents WHERE unikey="x128or256".

Удаление пустых значений из массиваarray_diff($array01,array02), где array01 — массив, из которого надо удалить пустые значения, а array02 — массив с единственным пустым элементом.

Вставка значений в таблицу с подсчётом значения методом отправки подзапроса к этой же таблице (INSERT с вложенным подзапросом SELECT):

если вам нужно вставить в таблицу запись, значения в которой будут производными от значений других записей в этой же таблице – то, скорее всего, вы попытаетесь создать запрос вида «INSERT INTO mytable SET myvalue = (SELECT max(myvalue) FROM mytable)» и получите в ответ что-то вроде «#1093 - You can't specify target table "mytable" for update in FROM clause». Можно ли обойти это досадное препятствие? Легко: «INSERT INTO mytable SET myvalue = (SELECT itsmytable.myvalue FROM (SELECT max(myvalue) AS myvalue FROM mytable)itsmytable)».

Комментарии

добавить комментарий

комментариев не найдено — ваш может стать первым!


© Taxpert. Интернет-мастерская М. Ю. Уткина.