Mr.KTO blog

  • Контакты
  • Поиск
  • Великие дела нужно начинать не раздумывая,
    Дабы мысль об опасности не ослабляла отвагу
    Г.Ю. Цезарь

Архив рубрики «PHP»

file.php / Открыть с помощью... / PHP.EXE

15 октября 2008

Иногда, когда скрипт написан для коммандной строки, хочется запустить его сразу из меню проводника windows.

Ну, вообще-то, любой .php-файл можно открыть с помощью интерпретатора php.exe. По правой кнопке на файле / Открыть с помощью / и выбираем путь к файлу php.exe. Можем даже в свойствах .php-файла указать использовать php.exe для открытия по двойному щелчку (хотя вряд ли это кому-то нужно).

Итак, в любой папке создаём файл с именем php_batch.bat и пишем в него:

@echo off
echo ---------------------------------
echo * Running %~nx1...
echo _________________________________
echo *** Press any key to continue ***
echo ***     or Ctrl+C to stop     ***
echo ---------------------------------
pause >nul
SET start=%TIME%

C:\PHP\php.exe -f %1

echo.
echo ---------------------------------
echo * Finished %~nx1
echo _________________________________
echo ** Start = %start%
echo ** End   = %TIME%
echo ---------------------------------
pause >nul

Используем его, как я описал выше. Хотя можно ещё: Свойства папки / Типы файлов / php / Дополнительно / Создать / Действие: "Запустить в batch-режиме", Приложение: <путь к нашему *.bat>. Тогда в меню по правой кнопке появится соответствующий пункт.

В конце выводится время начала/окончания работы запускаемого php-скрипта, включая миллисекунды. (p.s.: %TIME:~0,-3% - время без миллисекунд).

Мы также можем выводить постранично результат работы скрипта, если напишем: C:\PHP\php.exe -f %1 | more

_________________________________________________________

Подробнее о bat-файлах и коммандной строке windows.

Кэшировние в 2 строчки

7 октября 2008

Ну, в 3. Или 4...

if (is_file("scriptname.session") && ($t = time() - filemtime("scriptname.session")) < $CACHE_TIME) {
    $dataModel = unserialize(file_get_contents("scriptname.session"));
} else {
    /* делаем что-то, и сохраняем данные в объекте $dataModel */
    $f = fopen("scriptname.session", "w") and fwrite($f, serialize($req)) and fclose($f);
}

Неплохо было бы добавить auto chmod – автоматическую установку прав доступа к файлу:

if (is_file("scriptname.session") && (is_readable("scriptname.session") || chmod("scriptname.session", 0777)) &&...

При этом не забывать про безопасность – закрытие доступа к файлам *.session:

Это может быть папка с Deny from all в .htaccess.
Или .htaccess в текущей папке с

<Files *.session>
    Order allow,deny
    Deny from all
</Files>

Примечания:

  1. Мы используем функцию is_file, а не file_exists, т.к. вторая проверяет существование как файла, так и директории.
  2. В переменной $t мы сохранили сколько секунд назад истёк кеш.
  3. $CACHE_TIME = 15*60; – время истечения кеша в секундах (15 минут).
  4. $dataModel – перменная или объект класса, содержащий сессионные данные.
  5. Вместо file_put_contents (PHP 5 only) мы записываем сериализованные данные в файл в одной строчке через and (чтобы следующая ф-ция выполнялась только если предыдущая вернула не-false). Мы не используем &&, ибо приоритет операций.

Форматирование кеш-даты:

Далее »

Когда переходить на ООП? I. Зачем использовать классы вместо функций.

22 июля 2008

Увидев первый раз такой код (например здесь), обычный человек, не сталкивавшийся до этого с ОО-программированием сразу скажет: «Спасибо, нам этого добра не надо. Обойдусь как-нибудь функциями».

Можно долго повторять, что всё новое человек воспринимает с подозрением, что нужно заставить его поверить... Но, вопрос в том, когда стоит использовать классы вместо функций. Ради чего стоит переходить от процедурного подхода к объектно-ориентированному?

1. Сохранение состояния (напр. cookie, referer при HTTP-запросах)

Итак, нужно совершить 2 последовательных HTTP-запроса, сохранив при этом номер последней ошибки (или 0), реферер и кукисы:
$p_content = submit_request("http://www.google.com/advanced_search?hl=ru", "", $last_error, $req_referer, $cookie_ar);
$p_content = submit_request("http://www.google.com/search?hl=ru&as_q=Mr.KTO&num=100", "", $last_error, $req_referer, $cookie_ar);

Здесь производится запрос к гуглу через форму advanced_search (т.к. до недавнего времени нельзя было сразу, без cookie вернуть 100 результатов на страницу). Куки сохраняются в глобальной переменной, массиве $cookie_ar, а функция submit_request принимает этот массив по ссылке:
function submit_request($req_url, $req_POST, &$last_error, &$req_referer, &$cookie_ar) { /*...*/ }

Если для вашей конкретной задачи такой код подходит... – оставьте его! Я серьёзно.

Как только вам понадобится совершить в промежутке между первым и вторым запросом к гуглу, третий запрос (вдруг приспичило проверить PR :)) – то возникнет проблема с корректностью $req_referer$cookie_ar, если куки не распределены, как массивы по доменам). Чтобы решить проблему, нам придётся ввести 3 новые глобальные переменные $req_referer_PR, $cookie_ar_PR, $last_error_PR.

Как это будет выглядеть в виде класса:

<?php
class qrl {
     //public:
     var $last_error = 0;
     var $req_referer = "";
     var $cookie_ar = array();

     function submit_request($req_url, $req_POST = "")
     {
          /*...*/
     }
}

// создаём объекты класса qrl
$req = new qrl; // для гугл-поиска
$PR  = new qrl; // для проверки PR

$req->submit_request("http://www.google.com/advanced_search?hl=ru"); //1
echo "PageRank:" . $PR->submit_request("http://toolbarqueries.google.com/search?ch=$hash&q=info:".urlencode($url));
echo "GoogeSearch:" . $req->submit_request("http://www.google.com/search?hl=ru&as_q=Mr.KTO&num=100");

?>

Теперь нам не нужно каждый раз придумывать (и писать) 3 переменных, они все храняться в свойствах класса. К тому же, современные PHP-редакторы поддерживают autocomplete (т.н. Code Insight), достаточно после -> нажать Ctrl+space, чтобы появился список всех публичных свойств и методов класса.
Далее »

Синонимайзер на PHP – достаточно одной строчки

11 июля 2008

Как лучше назвать: синонимайзер или синонимизатор. Можно просто написать: "синоним(айзер|изатор)", после чего передать эту строку php-функции, в результате получив одно из написаний. Это и будет синонимизация контента, т.е. генерация уникальных описаний.

Единственное, что я не понимаю – зачем делать из этого событие. Потому что достаточно одной строчки на PHP.

Итак, имеем строку $s:

$s = 'Чтобы начать (работать|валять дурака|сходить с ума) надо заняться (спортом|сексом|чтением блогов)';

Всё, что нужно – в следующей строчке:

echo preg_replace('/\(  (.*?)  \)/xse', '$ar[array_rand($ar = explode("|", "\\1"), 1)]', $s);

В итоге получилось вот это.

Здесь стоит предупредить, что строка $s НЕ ДОЛЖНА БЫТЬ ДОСТУПНА ДЛЯ РЕДАКТИРОВАНИЯ ПОЛЬЗОВАТЕЛЮ. Иначе мы получим выполнение произвольного php-кода :).

Чтобы этого не было, и чтобы разобраться подробнее: Далее »

Шаблонизировать за 6 секунд (и 6 строк)

29 ноября 2007

По мотивам: LARIN.in – Прощай Smarty или простой шаблонизатор.

Я тоже не люблю Smarty. Не только потому, что это – не мой php-класс. А потому, что разработчики Smarty действовали по принципу "идеальное решение для всех". Эта излишность просто мозолит глаз: здесь и разные форматы имён переменных, и модификаторы (д.б. в css или в php-коде), временные переменные в циклах, слишком много слов (имена аттрибутов функций, начало/конец цикла). При том, что даже кэшированный в php код тормозит. И не говоря о том, что сам класс огромен и вы зависите от выпусков обновлений.

Я же следую (раньше – неосознанно) принципам экстремельного программирования. То есть, реализовывать возможности программы только по текущим потребностям. Не более. (Исключение – "правило пяти минут": если что-то можно сделать меньше, чем за 5 мин. – это надо сделать немедленно, т.к. на возврат к делу (чтобы загрузить программу в голову) уйдёт очень много времени.)

Спорить о том, зачем нужен шаблонизатор можно долго. Я считаю, что в каждом конкретном проекте нужно использовать минимальный шаблонизатор, выполняющий наилучшим образом необходимые задачи. То есть, если, например, требуется сократить размер шаблонных конструкций (по сравнению с php-шаблонами), или сделать так, чтобы шаблон можно было удобно редактировать в Dreamweaver – нужно написать такой шаблонизатор.

У меня уже есть один. Но для текущего проекта я решил придумать новый. Всё гениальное просто:

класс шаблонизатора:

class View {

    function parse_page($source_file) //public
    {
        include($source_file);
    }
}
пример шаблона:

<html>
<head><title><?=$this->title?></title></head>
<body>
  <table>
<?php foreach($this->companies as $k => $v) { ?>
    <tr><td><?=$k?></td><td><?=$v?></td></tr>
<?php } ?>
  </table>
</body>
</html>
использование:

require_once("inc/View.php");

$view = new View;

$view->title = "Page title here";
$view->companies = array("Apple" => "iPod", "Microsoft" => "Windows", "Google" => "AdSense");

$view->parse_page("skin/tskin.php");
Страница 1 из 3123»