Полезные php трюки.
Несмотря на свою легкость и универсальность, php является очень функциональным языком. Он не такой гибкий, как C конечно, но и у него есть свои хитрости. Я еще не матерый профессионал в области программирования на php, но уже успел нахвататься несколько php трюков и хитростей при работе на php.
В этом посте я составил небольшую подборку, которая будет полезна как новичкам, так и некоторым профессионалам.
Меняем массив через foreach.
Почти в любом php-скрипте используются массивы, а следовательно, и циклы. Самым популярным является цикл foreach. При обработке массивов этим циклом, очень часто приходится их изменять, но как, вы уже успели заметить, если сделать так:
foreach ($categories as $cat) { $cat['name'] = 'some cat'; }
То ни один элемент массива $categories не пострадает Другими словами, поле name у каждого элемента останется прежним, а не изменится на “some cat”.
Это происходит из-за того, что цикл foreach работает не с самим массивом, а его копией. Почти все знают, что это можно исправить так:
foreach ($categories as $k=>$cat) { $categories[$k]['name'] = 'some cat'; }
Но, есть и еще один вариант. Мне этот вариант больше нравится, он более наглядный и с ним проще работать, когда есть вложенные циклы:
foreach ($categories as &$cat) { $cat['name'] = 'some cat'; } unset($cat);
Отличие этого способа в том, что здесь в каждой итерации создается ссылка-переменная $cat для текущего элемента массива. А для того, чтобы в дальнейшем она не занимала память – она удаляется через unset().
Передаем массивы в функции.
Вторая частая ситуация – это когда в функцию надо передать много параметров, но этого сделать нельзя из гуманных и эстетических соображений В таких случаях их передают в виде массива.
Например, нам надо передать информацию о пользователе в метод какого-то класса:
$user = array( 'name' => $name, 'surname' => $surname, 'age' => $age, 'country' => $country, 'city' => $city, 'zipcode' => $zipcode, 'login' => $login ); Users::Add($user);
Полей может быть еще больше. Допустим, что этот метод добавляет пользователя в БД.
function Add($user) { $sql = 'INSERT INTO users (name, surname, age, …) VALUES (‘.$user[‘name’].’, ‘.$user[‘surname’].’…)'; mysql_query($sql); }
Довольно сложно будет потом прочитать этот запрос, не правда ли? Но есть один способ его сократить, точнее функция:
function Add($user) { extract($user); $sql = ‘INSERT INTO users (name, surname, age, …) VALUES (‘.$name.’, ‘.$surname.’…)’; mysql_query($sql); }
Функция extract преобразовывает массив в переменные. Кстати говоря, такой php трюк применяется в исходниках wordpress.
Использование переменных переменных.
Да, это не опечатка. В php есть такая интересная возможность.
$var_name = 'my_var'; $$var_name = 'hello'; echo $my_var; // выведет ‘hello’
Другой способ:
${'my_var'} = 'hello'; echo $my_var; // выведет 'hello';
Более того, можно и функции так использовать:
function show_msg($msg) { echo $msg; } $func = ‘show_msg’; $func(‘Hello’); // выведет ‘Hello’.
Но это скорее малоизвестная возможность, чем хитрость. А хитростью можно назвать использование недопустимых имен переменных в php, с помощью этой конструкции:
${1} = ‘Hello’; echo ${1}; // выведет ‘Hello’
В этом коде используется переменная с именем 1, что недопустимо по правилам php
Игнорируем браузер пользователя.
Я сам редко сталкивался с такой ситуацией, но для больших проектов это наверняка часто встречающаяся проблема. Предположим, что скрипт выполняет какие-то запросы в базе данных (удление/добавления/редактирование) и во время этого пользователь нажимает кнопку Stop в браузере. По этой команде php скрипт завершает свою работу, что, в нашем случае может оказаться чреватым нарушением целостности базы данных.
Эта проблема решается функцией ignore_user_abort():
ignore_user_abort(true); … выполяем запросы к БД… ignore_user_abort(false);
Пока что все. Удачи и до встречи.
cryptus.
Было интересно и, думаю, полезно узнать про “игнорирование пользователя”. Про такой момент защиты целостности данных приложения не знал раньше. Спасибо за просвещение!
Если в БД использовать транзакции, то целостность данных пострадать не должна 😉
>Меняем массив через foreach.
доступно в php5, некрофилы таким трюком не могут воспользоваться 😉
>Передаем массивы в функции.
только не стоит забывать что напрямую данные в запросы не стоит передавать. и проще только ORM 😉
2Илья Земсков: Я сам недавно узнал 😉
2Konstantin: Из встроенных механизмов защиты целостности данных MySQL слышал только про триггеры и внешние ключи. Для их реализации нужно использовать движок InnoDB (может еще какие-то поддреживают), который не все хостинги поддерживают. Насчет транзакций не знал раньше - интересная тема, спасибо за наводку
2DYPA: Не знал про ограничение на 5 версию пхп только, спасибо.
Насчет фильтра ввода - это да, фильтровать можно либо внутри метода (тем самым скрыв реализацию от уровня абстракции выше), либо фильтровать данные перед передачей внутрь функции. А вот насчет ORM раньше не слышал, спасибо - покопаю эту тему
применение функции extract чревато неожиданными последствиями, особенно если вы автоматизируете процесссы вставки данных в таблицы с большим числом полей
2zoonman: Согласен, нужно все варианты продумать прежде чем ее использовать.
function Add($user) {
$sql = ‘INSERT INTO `users` (`’.join(‘`,`’,array_keys($user).’`) VALUES (“‘.join(‘”,”‘,$user).'”)';
mysql_query($sql);
}
Вообщем блог класный, но бывают такие моменты когда кажеться что читаеш букварик Слабовато однако ! )) Пока ничего нового не нашел, но надежда есть ! Удачи !
Ну здесь иногда бывают статьи и для новичков, поэтому Вам так кажется, Ростислав )
Да все верно )) Блог класный, добавил в закладки !
А есть такие трюки …
См. книгу “PHP ТРЮКИ” Джек Д. Харрингтон
Спасибо! Будем использовать при строении сайта.
Почему-то не работает команда ignore_user_abort позволяющая работать программе записи КЭШ даже ночью, при отключённом браузере?
Для программы формирования КЭШа не нужно право работать час в дневное время. Просто до срабатывания по таймауту она делает перезагрузку, следующее время записывается в cache1\sled_time.txt. Время, требуемое для формирования КЭШа 6 минут, а стандартный таймаут = 30 секунд. Как выяснилось, основное время составляет не загрузка картинок от баннеров из Интернета, а проверка есть ли ссылка и если она есть, есть ли картинка в Интернете. Тогда КЭШ должен работать на сервере. Приведённые программы несколько избыточны, так как они служат для отладки.
Начальная: vakuzmenok.narod.ru/time_nach5.php и основная: vakuzmenok.narod.ru/runing5.php программа.
Некоторые моменты в программе: В круглосуточной записи на удалённом сервере die() не работает, видно так сконфигурирован сервер. Использование в начале и конце теги HTML, т.к. используются подпрограммы на JavaScript, а без данных тегов они не работают. Сразу после запуска программа проверяет в главной = текущей директории наличие подкаталогов cache1 и cache2, файлов cache1\form_kesh.txt, cache1\time.txt,cache1\close_cache.txt, cache1\sled_time.txt, cache1\statuscache.txt cache1\readcache.txt, cache1\time_nach.txt, которые можно создать пустыми. Если чего-то нет, то остановка и выдаётся соответствующее сообщение. Если встретится файл cache1\stop_runing.txt то программа останавливается.
Работа данной программы проверена под php 5.2.3 и 4.3.9, всё равно функция ignore_user_abort не работает под разными браузерами (пробовал под Лисой и Оперой), т.е. работа программы прекращается при закрытии браузера или нвжатия клавиши Стоп (остановка видна в браузере)(в файл cache1\time.txt перестаёт писаться текущее время, как на локальном, так и на удалённом сервере, а иначе пишется каждые 10 минут).
Ответ с хостинга: Вы можете выполнять скрипт по расписанию с помощью планировщика заданий cron…
Оказывается после выхода из браузера при использовании команды ignore_user_abort. скрипты работают только с абсолютными путями.
Возможно Вас заинтересует проект cms.skobka.com. В большей степени это фреймворк для разработчиков, потому что делали для себя)
Ну а потом просто решили поделиться =)
Шайтан, достаточно интересных моментов почитал ) Удачи.