CakePHP action из командной строки

Эх, если бы создатель PHP знал как будут мучать его "простенький скриптовый язык для домашних страниц". Я сам использую его часто для таких задач, для которых намного лучше подошли бы Perl, C# и Java. Но так как их знаю в режиме read-only, то у меня получается писать более эффективный код на PHP.

Меня в таких случаях раздражают 2 вещи:
1. Отсутствие многопоточности
В основном для загрузки/закачки одновременно нескольких файлов с нескольких серверов. Для загрузки обхожусь multi_curlом, для закачки можно написать алгоритм с неблокирующими сокетами. То есть, при желании, можно обойтись.
Для других задач можно также создавать другие процессы, но это не работает под Windows.

2. Проблемы с долгими скриптами
Известная ошибка Request timeout возникает, если не передавать никаких данных в браузер долгое время (вроде 30 секунд). Решается тем, что периодически выводится какой-то текст.

Я решал вторую проблему тем, что писал скрипты не в CakePHP и запускал их напрямую через php /path/to/script.php. Но ведь так хорошо было бы запускать CakePHP actions с командной строки, чтобы вешать их на cron.

Shells+Tasks теоретически могли бы подойти, но хочется, чтобы можно было запускать напрямую любой action.

Сейчас это выглядет вроде

45 * * * * /usr/bin/lynx -source http://example.com/controller/action
или
45 * * * * /usr/bin/wget -O - -q http://example.com/controller/action

(скопировано с задачи обслуживания Drupal)

А хотелось бы
45 * * * * php /home/www/example.com/index.php controller/action

И, оказывается, что решается это удивительно просто. В config/bootstrap.php добавляется

PHP:
  1. if (!empty($_SERVER['argv'][1])) {
  2.     $_GET['url'] = $_SERVER['argv'][1];
  3.     Configure::write('CLI', 1);
  4. } else {
  5.     Configure::write('CLI', 0);
  6. }

и можно запускать actions из командной строки.

В начале функций, которые выводят статус для того, чтобы передать что-то в браузер добавляется проверка

PHP:
  1. if (Configure::read('CLI')==1) return true;

, чтобы не мусорить stdout и не отвлекать php от основной задачи.

Насколько я знаю, сейчас связка Apache-PHP сделана довольно хорошо и от того, что скрипт запускается из командной строки, скорость выполнения практически не меняется, так что это просто для уверенности в том, что скрипт будет работать до конца.

Только не забывайте, от чьего имени выполняется скрипт. Потому что можно создать как root кучу файлов и папок, а потом apache не сможет получить к ним доступ.


Понравилось?

  1. Подпишись через RSS
  2. Расскажи о http://php.southpark.com.ua друзьям.
    Все способы хороши: ICQ, E-mail, свой блог, комментарий в чужом блоге или сообщение на форуме
  3. Добавь статью на news2.ru, Хабрахабр или в закладки

Огромное спасибо!

И не стесняйтесь комментировать - у меня стоит плагин, который убирает rel="nofollow" у людей, которые написали больше 5 комментариев.

RSS feed | Trackback URI

7 комментариев »

Comment by farik
2008-02-21 17:07:48

Сорри, за оффтоп, но поскольку не нашел мыла пишу сюда.
Есть ли у Вас книги по кейку?

2008-02-23 23:40:59

Полноценных книг по CakePHP, насколько я знаю, пока нет
Можно пока смотреть http://book.cakephp.org/

 
 
2008-03-09 11:50:03

Привет Владимир...

не нашел контактов по этому пишу здесь...

как бы свами связаться ?
есть несколько вопросов... по административному интерфейсу проекта на cakePHP...

мой icq: 32904330

 
Comment by Yaroslav Vorozhko Subscribed to comments via email
2008-03-11 16:05:08

>Известная ошибка Request timeout возникает, если не передавать никаких данных в браузер долгое время (вроде 30 >секунд).
300 секунд, но чтобы браузер не прерывал выполнение скрипта, существует функция set_time_limit, при значении 0 скрипт может исполняться вечно.

>Насколько я знаю, сейчас связка Apache-PHP сделана довольно хорошо и от того, что скрипт запускается из командной >строки, скорость выполнения практически не меняется, так что это просто для уверенности в том, что скрипт будет >работать до конца.
При запуске php скрипта из командной строки apache процесс вообще не создается :twisted: . Свзяка Browser -> Apache -> PHP -> OS, становиться PHP -> OS.

2008-03-14 10:07:29

даже с set_time_limit процесс прерывается, приходится что-то посылать в output каждые 20 секунд.

честно говоря, я не очень хорошо представляю как работает Browser< ->Apache< ->PHP< ->OS, но у меня ощутимого прироста производительности из консоли не наблюдалось (сравнивал на задачах, которые выполняются больше 20 часов)

 
 
Comment by Yaroslav Vorozhko Subscribed to comments via email
2008-03-14 10:28:13

Есть очень много факторов влияющих на производительность. Может как раз в твоем случае bottleneck был не в скрипте, а как часто бывает в взаимодействии с базой данных. При интенсивном использовании БД запуск из командной строки не будет сильно отличаться от запуска из браузера, если не считать тех вкусных фич, которые можно делать с помощью командной строки.
Задачи по 20 часов запускать с браузера глупо, так как утечки памяти в браузере или сторонние приложения могут повлиять на его работу и скрипт может оборваться не завершившись.
Кроме set_time_limit есть еще max_execution_time, но не стоит с ними заворачиваться запускай 20 часовой скрипт из браузера. Лучше уж командная строка.
Кстати не всегда возможно посылать в бразуер порцию html кода во время выполнения скрипта, так как могут быть выключена настройка автоматического flush и весь вывод будет храниться в кеше до последней строки выполнения скрипта.

2008-03-14 21:33:24

> Задачи по 20 часов запускать с браузера глупо
поэтому и не запускаю :smile:

сейчас дошёл до того, что использую для мелкой обработки данных вместо перетягиваний и фильтров в Excel (который очень люблю), скрипты в 10 строк на PHP из коммандной строки.

 
 
Имя (required)
E-mail (required - never shown publicly)
URL
Текст комментария
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> in your comment.