Однажды, переходя со связки nginx+apache2+mod_php на связку nginx+php-fcgi я столкнулся сразу с двумя проблемами. Во-первых это очень серьезная проблема уязвимости которая обсуждается например тут, и которая позволяет злоумышленнику при некоторых обстоятельствах загрузить вредоносный скрипт под видом обычной картинки и потом выполнить его, а во-вторых это отсутствие передачи GET-параметров при использовании конструкции try_files с откатом на /index.php: “try_files $uri /index.php” в качестве замены mod_rewrite для перенаправления всех запросов на index.php…
Переодически при разработке различных проектов перед нашей командой встает задача запуска PHP-скрипта в бекграунде для выполнения каких-либо действий, будь то какое-то длительное импортирование или граббинг чего-либо с переодическим оповещением о статусе процесса. И каждый раз после пробного выполнения команды вроде “$ php -q script.php > script.log &” мы получаем то, что скрипт перестает выполняться сразу же после запуска: “[1]+ Stopped php -q script.php > script.log”.
Причиной тому является определенное поведение PHP-интерпритатора когда он теряет связь с запустившим его клиентом, а в данном случае — с вводом командной строки.
Если изучить PHP-документацию по работе с соединениями, то оттуда можно узнать что таким поведением можно управлять при помощи директивы конфигурации или же функции вызываемой непосредственно в самом PHP-скрипте — ignore_user_abort. Таким образом, по идее, остановка выполнения PHP-скрипта после отсоединения клиента не должна происходить если включить игнорирование отсоединения клиента, но мы, к сожалению, не смогли добиться нужного поведения при использовании этой директивы или функции и PHP-скрипты запускаемые в бекграунде продолжали “умирать” сразу же после запуска.
Сейчас уже эта проблема конечно же не вызывает ни ступора, ни поисков нужной информации, но в свое время “съела” несколько часов на поиск нужного решения и проверку/отладку найденного способа, поэтому я хочу во-первых поделиться со всеми читателями данным трюком, а во-вторых — написав этот пост и освежив тем самым в памяти способ решения данной проблемы еще лучше запомнить его на будущее когда опять нужно будет вспомнить как же правильно запускать PHP-скрипты в бекграунде
Итак, решение очень простое — нужно дать PHP-скрипту то, что ему нужно — поток ввода, который он будет считать клиентом и не будет завершать свою работу:
1 | $ php -q script.php < /dev/null > script.log & |
После запуска подобной команды PHP-скрипт не “умрет” сразу же после запуска, а продолжит запланированную работу до тех пор пока ее не выполнит!
Надеюсь что этот небольшой хинт поможет кому-то сэкономить пару часов!
Если вы установили браузер Google Chrome и начали что-то искать через omnibox находясь при этом например в России, то скорее всего при первом поисковом запросе baseURL установится на http://www.google.ru/, и все ваши поисковые запросы будут открываться именно через google.ru.
Многие хотят использовать по умолчанию google.com (да и еще через https) и как же это сделать?!
Если в своих проектах вы используете библиотеку jQuery и работаете в такой популярной IDE как Eclipse, то вам, видимо как и нам, точно должно нехватать удобного Content Assist’а для просмотра и подстановки нужных jQuery-методов. И почему команда jQuery не выпустит специальную неминимизированную версию с нормальными комментариями к методам в формате JSDoc?! Скорее всего у них, так же как и у нас, очень много работы, и тратить свое время на написание специального файла покрывающего документацией весь функционал всех методов jQuery они не могут. А мы в свою очередь иногда не можем (не хотим) позволить себе просматривать документацию в поисках нужного метода. И тут нам поможет Content Assist для JavaScript в Eclipse…
Странно что Apple не реализовала в своем файловом менеджере Finder функцию “Cut” (“Вырезать”) для файлов в привычном для нее смысле. Хотя если раскрыть ниспадающее меню “Edit” при выделенных файлах, то там красуется неактивный пункт “Cut (Cmd+X)” – зачем он там? Правильно! Вырезать кусочки текста при редактировании имен файлов! Но никак не для перемещения файлов. Получается некоторая дискриминация для тех кто предпочитает использовать клавиатуру для работы с файловыми массивами по средством Finder’а, так как Apple пропагандирует повсеместное использование Drag&Drop для перемещения файлов.
Далее я хочу рассказать о простом решении данной проблемы несколькими способами…
Как говорится в этой статье нужно немного отредактировать eclipse.ini который лежит в пакете Eclipse.app.
Изменить нужно всего 3 строчки:
1 2 3 | -Xms40m -Xmx384m -Dosgi.requiredJavaVersion=1.5 |
следующим образом:
1 2 3 | -Xms80m -Xmx768m -Dosgi.requiredJavaVersion=1.6 |
удвоив значения для выделяемой памяти -Xms и -Xmx, и изменив требуемую версию Java-машины с 1.5 на 1.6 (Java 1.6 должна быть установлена, проверить можно командой “java -version” в терминале).
Так же возможно это поможет ускорить Eclipse на Windows-платформах (мой Эклипс на Win7 помоему стал немного шустрее по откликам в интерфейсе).
Многие разработчики которые работают одновременно и с PHP и с JavaScript знают как в JS легко получить первый (и, скорее всего, единственный) элемент массива возвращенного функцией и сразу же использовать его:
1 | var body = document.getElementsByTagName('body')[0]; |
Но, скорее всего, немногие знают, что в PHP можно делать так же: получать первый элемент возвращаемого функцией массива в одной строчке:
1 | $first_tag = current($post->getTags()); |
Функция current() возвращает элемент на котором в данный момент установлен внутренний указатель массива.
Допустим у нас есть изображение при правом клике мыши на которое вы не хотите чтобы отображалось контекстное меню браузера, или же вы хотите отобразить свое контекстное меню для какого-то элемента на странице…
Для отлова события при клике на элемент правой кнопкой мыши есть параметр “oncontextmenu”:
1 | <img src="..." oncontextmenu="return false;"/> |
Код “return false;”, который выполняется при наступлении этого события в примере выше, приводит к тому что контекстное меню не показывается. Тут так же можно разместить вызов любого вашего метода для отображения вашего контекстного меню…
Недавно в своем Google Reader’е я наткнулся на интересную запись о том, что китайцы начали рисовать карты своих городов в 3D! Отрисовано уже несколько десятков городов, и, скажу я вам, детализация просто поражает воображение!
Прямо SimCity какой-то!
Побродить по картам “вживую” можно тут: http://sh.o.cn/, http://www.o.cn/, http://gz.o.cn/, http://www.jc08.com/.
Если вам нехватает понимания китайских иероглифов, то советую вам установить Google Chrome – он в автоматическом режиме предлагает перевести страници на ваш язык.
Этой статьей я хочу открыть новую тему в своем блоге, посвященную разработке на Flash/Flex/ActionScript3. Итак приступим.
Flash Player 10.0
Начиная с версии 10.0 во Flash Player появилась очень интересная возможность, которая позволяет устанавливать прямые соединения между плеерами при помощи сервиса Stratus:
1 2 3 | nc = new NetConnection(); nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); nc.connect('rtmfp://stratus.adobe.com/YOUR_DEVELOPER_KEY_HERE'); |
Этот сервис выполняет роль организатора: подключившись к нему ваш клиент получает уникальный Peer ID, зная который, другие такие же как и вы клиенты, могут напрямую подключаться к вашему клиенту и подписываться на данные, которые вы публикуете.
Давайте рассмотрим эту схему более подробно, по шагам:
- Flash-клиент в вашем браузере соединяется с сервисом Stratus
- В клиенте создается поток (NetStream), в который начинается публикация какого-то контента
- Другие flash-клиенты также соединяются с сервисом Stratus
- В них создаются потоки, которые подключаются к вашему клиенту по его Peer ID и подписываются на контент от него
Это самая простая схема: один клиент публикует контент, а другие подписываются на получение контента.
Но давайте попробуем усложнить эту схему. Что если каждый клиент и публикует и подписывается на потоки всех известных ему клиентов?








