Статьи

Иногда бывает, что в Mozilla Firefox скрипты написанные на языке сценариев JavaScript работают нормально, в MsIE появляется ошибка, что "Предполагается наличие }" и номер последней строки файла :(

Возможная причина этой ошибки в том, что код, который передается через Ajax запросы в MsIE "склеивается" в одну строку и любые однострочные комментарии // или отсутствие ; в конце функции вызывает ошибку.

Вывод такой: все JavaScript, которые передаются Ajax запросами, делать по-возможности без комментариев, не забывать ; в конце и тестировать на работоспособность в MsIE


Решил использовать полезную особенность Oracle под названием bind в PHP5.

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

Написал цикл, в котором будет вызываться функция oci_bind_by_name:

	foreach($array_bind as $k => $v) {
		oci_bind_by_name($s, $k, $v);
	}

Полезли ошибки Oracle. Все переменные заменялись последним передаваемым элементом массива. :( Долго не мог понять в чем дело... Пока не нашел в Интернете, что передавать значение текущего элемента массива, для функции oci_bind_by_name, нужно по ссылке, а не по значению. Так что правильный вариант вызова для цикла foreach должен выглядеть так:

	foreach($array_bind as $k => $v) {
		oci_bind_by_name($s, $k, $array_bind[$k]);
	}

Теперь пользуюсь функцией oci_bind_by_name в циклах foreach и работаю с замечательной возможностью Oracle под названием bind.


Возникла задача: переименовать все файлы и папки, имена которых начинаются на символ решетки # на имена без решетки в ОС Linux. Вот как эту задачу можно красиво решить на Perl в одну строку:
perl -MFile::Find -e 'find sub{ rename $_, (m/#(.*)/)[0] }, q{.}'

Иногда нужно эмулировать register_globals = On, когда этот параметр установлен в Off и доступа на его изменение нету. Или нужно это делать не для всего кода, а для каких-то старых и/или коряво написанных скриптов.

Тогда можно воспользоваться таким решением:

    foreach($_SERVER as $k=>$v) $$k=$v;
    foreach($_ENV as $k=>$v) $$k=$v;
    foreach($_FILES as $k=>$v) $$k=$v;
    foreach($_COOKIE as $k=>$v) $$k=$v;
    foreach($_POST as $k=>$v) $$k=$v;
    foreach($_GET as $k=>$v) $$k=$v;

которое можно поместить в отдельный файл и подключать его с помощью require_once вначале работы скрипта.


Комментарии по теме (PHP):

Alexey Miroshko: есть хорошая функция extract ;)
Отправлено: [04.11.2008 13:20:24]


Данная заметка не претендует на исчерпывающее руководство по PHP, cURL, протоколу HTTPS и Cookie. Если Вы ищеете такую информацию, то заходите на официальные сайты или ищите в Google ;)

Просто хотелось показать один из можных варинатов решения поставленной задачи: необходимо заходить роботом использующим cURL по протоколу HTTPS методом POST, выполнять действия в системе и выходить из системы. Данные о сессии пользователя хранятся в Cookie.

Я не буду вдаваться в подробности и публиковать полное решение, но выложу пример связки PHP + cURL + работа по протоколу HTTPS методом POST, а так же работа с данными Cookie.

Приведу часть примера, которая может решаеть подобную задачу:

// вход в систему
// имя хоста, куда будем заходить
$hostname = 'your.seruce.host.com';
// инициализация cURL
$ch = curl_init('https://'.$hostname.'/index.php');
// получать заголовки
curl_setopt ($ch, CURLOPT_HEADER, 1); 
// если ведется проверка HTTP User-agent, то передаем один из возможных допустимых вариантов:
curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3');
// елси проверятся откуда пришел пользователь, то указываем допустимый заголовок HTTP Referer:
curl_setopt ($ch, CURLOPT_REFERER, 'https://'.$hostname.'/index.php');
// использовать метод POST
curl_setopt ($ch, CURLOPT_POST, 1);
// сохранять информацию Cookie в файл, чтобы потом можно было ее использовать
curl_setopt ($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
// передаем поля формы
curl_setopt ($ch, CURLOPT_POSTFIELDS, 'user=your_robot&pass=Your_R0b0t!PassWd1&mod=Login');
// возвращать результат работы
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
// не проверять SSL сертификат
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
// не проверять Host SSL сертификата
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
// это необходимо, чтобы cURL не высылал заголовок на ожидание
curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Expect:'));
// выполнить запрос
curl_exec ($ch);
// получить результат работы
$result = curl_multi_getcontent ($ch);
// вывести результат
echo "\n".'Login OK'."\n".'[result ===8<===>'."\n".$result."\n".'<===>8=== result]'."\n";
// закрыть сессию работы с cURL
curl_close ($ch);

Вот мы и вошли в систему. ID сессии, которая передается в Cookie храним в файле, который мы передали в параметре CURLOPT_COOKIEJAR. Результат работы: заголовки + тело страницы получаем и выводим из переменной $result. Пока сессия не закончится можем выполнять необходимые действия в системе.

Если вывод будет идти в командную строку Windows, а кодировка системы с которой идет работа: cp1251, то можно воспользоваться спобом описанным в заметке "chcp - изменение кодовой страницы cmd.exe", чтобы видеть вывод в нормальной кодовой странице, а не древнечукотские манскрипты cp866 установленной по-умолчанию в командном интепретаторе.

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


UPD: 2013-04-03. Теперь архив версий доступен на другой страцнице: http://php.net/releases/index.php.

Столкнулся с проблемой: необходимо загрузить исходники PHP версии 5.2.6.

На сайте ссылка была только на PHP версии 5.2.9.

Пустил поиск через Google:
download php-5.2.6.tar.bz2

И в результатах поиска увидел ссылку:
http://ua2.php.net/get/php-5.2.6.tar.bz2/from/a/mirror.

Не уверен, что там лежат все старые версии, но думаю, что такой способ поиска более ранней версии дистрибутива PHP вполне приемлим.


Недавно делал одну небольшую систему на jQuery 1.3.2 и PHP4, которая по таймеру отправляла запросы к PHP-скрипту обработчику:

$.ajax({
	type: "GET",
	url: "somescript.php",
	datatype: "html",
	data: { param1: " <?=$param1?>", param2: " <?=$param2?>" },
	success: function ( data ) {
		$('#cMessages').html( 'Number of retry: ' + _max_retry + '. Status message: ' + data );
	},
	error: function ( xhr, ajaxOptions, thrownError ) {
		$('#cMessages').text('jQuery Ajax error! xhr: ' + xhr + '; ajaxOptions: ' + ajaxOptions);
	}
});

В Mozilla Firefox, Opera и Safari запросы отправлялись нормально, а вот в IE запрос отправлялся только один раз.

Причем никакого специального кеширования со стороны сервера нигде включено не было.

Немного поразмыслив решил добавить дополнительный параметр t, который каждый раз добавлял новое случайное значение к запросу:

$.ajax({
	type: "GET",
	url: "somescript.php",
	datatype: "html",
	data: { param1: " <?=$param1?>", param2: " <?=$param2?>", t: (new Date).getTime()  },
	success: function ( data ) {
		$('#cMessages').html( 'Number of retry: ' + _max_retry + '. Status message: ' + data );
	},
	error: function ( xhr, ajaxOptions, thrownError ) {
		$('#cMessages').text('jQuery Ajax error! xhr: ' + xhr + '; ajaxOptions: ' + ajaxOptions);
	}
});

После этого IE стал нормально отправлять запросы.


Чтобы узнать номер текущей строки в файле необходимо нажать комбинацию клавиш +g

Кроме этого отображается имя файла и общее количество строк в файле.


Недавно делал работы на сервере под пользователем root и обратил внимание на то, что в кроне есть задачи, с дампом баз mysql, но в параметрах подключения не были указаны имя пользователя и пароль, под которым они бы выполнялись. При этом задачи эти выполнялись нормально.

Поскольку мне еще нужно было проверить настройки сервера MySQL, то я запустил клиент mysql без параметров имя пользователя и пароль из командной строки и клиент открылся без запроса имени пользователя и пароля!

Когда я набрал команду

mysql> select user();

ответ был:

+----------------+
| user()         |
+----------------+
| root@localhost | 
+----------------+
1 row in set (0.00 sec)

В папке /root/ находился файл .my.cnf

с таким содержимым:

[client]
user=root
password=***********

Такой способ хранения пароля на первый взгляд может показаться не безопасным, но если настроить разрешения на файл правильно (chmod 600 /root/.my.cnf), то никто посторонний этот файл прочитать не сможет кроме его владельца пользователя root.

В таком случае выполнять административные задачи связанные с mysql удобнее и пароль хранится в безопасном месте.


Для удаления строк, слов и символов в файле существует команда d.

Команда dd удаляет одну текущую строку, на которой находится курсор.

С помощью команды Nd и нажатия стрелки мы удаляем N симолов (строк) в зависимости от нажатой стрелки.

Команды +d и d+$ удаляют строку до конца начиная с текущей позиции курсора.

Еще полезно бывает удалить все строки с текущей и до конца файла. Для этого служат команды: d+g или :.,$d


Часто возникает необходимость проверить какой-то перенесенный на новый сервер сайт, а запись DNS еще не обновилась (или по каким-то причинам не может быть обновлена). В таких ситуациях удобно добавить IP сервера и DNS имя сайта в системный файл hosts.

Для Windows семейства NT это можно сделать так: Пуск - Выполнить...

notepad "%windir%\system32\drivers\etc\hosts"

каждая строка содержит пару значений ip-адрес и доменное имя разделенных пробелом или табуляцией.

Для Linux и Unix систем можно внести запись в /etc/hosts

каждая строка содержит ip-адрес и имена доменов, которые ему соответсвуют, разделенные пробелами или табуляцией.

Обычно файлы hosts имеют более высокий приоритет чем запросы к DNS серверу.


Недавно столнулся с обыденной задачей. Необхимо было перенести сайт со старого сервера на новый. И на старом и на новом севрере был установлен MySQL версии 5.

После переноса на новый сервер сайт перестал работать. Проблема оказалась в том, что не работала одна из хранимых процедур. На новом сервере не была найдена встроенная функция PREG_REPLACE.

[taras@webhome ~]$ mysql -h localhost -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.0.83 Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SELECT TRIM(BOTH '-' FROM PREG_REPLACE('/[\\\\s-]+/', '-', PREG_REPLACE('/&[\\w#]+?;|[^\\w\\s-]+/', '', LOWER(" Test string & just for test!.. "))));
ERROR 1305 (42000): FUNCTION PREG_REPLACE does not exist

Посмотрев в поисковике я обнаружил, что это не стандрартная функция MySQL. Эта функция стандартна для PHP, а в MySQL есть UDF расширение lib_mysqludf_preg, которое выполняет аналогичные задачи.

Для установки этого расширения необходима библиотека PCRE: Perl-compatible regular expression library. Ее можно поставить через yum или из исходных текстов, как показано ниже:

[root@webhome install]# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.9.tar.gz
...
[root@webhome install]# tar -xzvf prcre-7.9.tar.gz
...
[root@webhome install]# cd pcre-7.9/
...
[root@webhome pcre-7.9]# ./configure
...
[root@webhome pcre-7.9]# make
...
[root@webhome pcre-7.9]# make install 

Установка самой библиотеки lib_mysqludf_preg из исходников выглядит так:

[root@webhome install]# wget http://mysqludf.com/lib_mysqludf_preg/lib_mysqludf_preg-0.7.0.tar.gz
...
[root@webhome install]# tar -xzvf lib_mysqludf_preg-0.7.0.tar.gz
...
[root@webhome install]# cd lib_mysqludf_preg-0.7.0
...
[root@webhome lib_mysqludf_preg-0.7.0]# ./configure
...
[root@webhome lib_mysqludf_preg-0.7.0]# make
...
[root@webhome lib_mysqludf_preg-0.7.0]# make install
...

Далее необходимо настроить MySQL. Для этого в секцию [mysqld] главного конфигурационного файла /etc/my.cnf установить значение переменной plugin_dir. В моем случае установленная библиотека lib_mysqludf_preg находится в /usr/local/lib.

После сохранения изменений в конфигурации необходимо перезапустить MySQL, например так:

[root@webhome lib_mysqludf_preg-0.7.0]# /etc/init.d/mysqld restart
Stopping MySQL:                                            [  OK  ]
Starting MySQL:                                            [  OK  ]

Теперь необходимо установить функцию PREG_REPLACE, для этого в клиенте mysql необходимо выполнить команду:

mysql> CREATE FUNCTION preg_replace RETURNS STRING SONAME 'lib_mysqludf_preg.so';
Query OK, 0 rows affected (0.08 sec)

Теперь установленную функцию можно использовать:

mysql> SELECT TRIM(BOTH '-' FROM PREG_REPLACE('/[\\s-]+/', '-', PREG_REPLACE('/&[\\w#]+?;|[^\\w\\s-]+/', '', LOWER(" Test string & just for test!.. "))));
+---------------------------------------------------------------------------------------------------------------------------------------------+
| TRIM(BOTH '-' FROM PREG_REPLACE('/[\\s-]+/', '-', PREG_REPLACE('/&[\\w#]+?;|[^\\w\\s-]+/', '', LOWER(" Test string & just for test!.. ")))) |
+---------------------------------------------------------------------------------------------------------------------------------------------+
| test-string just-for-test                                                                                                                   |
+---------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.03 sec)

Иногда необходимо принудительно заставить пользователя использовать шифрованное SSL (HTTPS) соединение. С помощью .htaccess это можно сделать так:


RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

Теперь, для папки и всех ее подпапок, в которой находится файл .htaccess с таким содержимым будет производиться автоматическая переадресация с использованием защищенного SSL (HTTPS) соединения.


Об этом написано в документации по селекторам http://api.jquery.com/category/selectors/:
If you wish to use any of the meta-characters (#;&,.+*~\':\"!^$[]()=>|/ ) as a literal part of a name, you must escape the character with two backslashes: \\. For example, if you have an an input with name=\"names[]\", you can use the selector $(\"input[name=names\\[\\]]\").
Если вы хотите использовать какие-либо мета-символы (#;&,.+*~\':\"!^$[]()=>|/) в качестве части имени, вы должны экранировать символ с двумя слэшами: \\. Например, если у вас есть поле ввода с именем = \"names[]\", вы можете использовать селектор $(\"input[name=names\\[\\]]\").


Эта заметка не претендует на исчерпываюеще руководство.
Это просто небольшая заметка, которая показывает один из возможных способов, возможно, не самый лучший.
Для выяснения всех деталей читайте документацию.
Для этой задачи необходимо использовать утилиту командной строки htpasswd.

1. Создание файла с паролем:

htpasswd -bcs /var/www/vhosts/shkodenko.com.ua/httpdocs/.htpasswd userName secretPassword

В данном примере мы запароливаем весь хост shkodenko.com.ua, файлы которого находятся в папке /var/www/vhosts/shkodenko.com.ua/httpdocs/
Имя пользователя userName и пароль secretPassword указываем прямо в командной строке (опция -b).
Создаем новый файл (опция -c).
Использовать SHA шифрование для пароля (опция -s).
Чтобы посмотреть все возможные варианты использования и опции служит команда htpasswd --help.

2. Обновляем .htaccess файл /var/www/vhosts/shkodenko.com.ua/httpdocs/.htaccess. Добавляем в него строки:

AuthUserFile /var/www/vhosts/shkodenko.com.ua/httpdocs/.htpasswd
AuthType Basic
AuthName "Password-protected Area"
Require valid-user


Время от времени возникает задача создать в файле .htaccess для веб сервера Apache редирект со старого имени домена на новое.

Редирект со статусом 301 означает, что сайт меняет свой постоянный адрес.

Это можно сделать добавлением таких строк в файле .htaccess на старом домене:


RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !shkodenko.com$ [NC]
RewriteRule ^(.*)$ http://shkodenko.com/$1 [L,R=301]


Если нужно запретить доступ пользователям веб сервера Apache ко всем файлам в папке кроме тех, чьи имена заканчиваются на .csv или .xml можно прописать такие правила в файл настройки .htaccess :

# Allow access to .csv and or .xml files
 <FilesMatch "(.*.csv|.*.xml)$">
Order allow,deny
Allow from all
 </FilesMatch>
# Deny access to all files
Order deny,allow
Deny from all

Если нужно запретить доступ пользователям веб сервера Apache ко всем файлам в папке, то этого можно добиться такими правилами файла настройки .htaccess :


order allow,deny
deny from all


Чтобы увеличить для сайта максимальный объем загружаемого файла для PHP скриптов, если сайт работает как модуль веб сервера Apache через файл настройки .htaccess необходимо добавить строки:

 <IfModule mod_php5.c>
php_value upload_max_filesize 8M
php_value post_max_size 16M
 </IfModule>

Где 8M максимальный объем загружаемого файла.


При работе с Vim бывает полезно задать настройки отступов в коде.

Например, для Linux shell сркиптов я использую такую строку:

# vim:ts=2:sts=2:sw=2

Эти настройки должны находится в последней строке файла.

Для Perl сркиптов я использую такую строку:

# vim:ts=4:sts=4:sw=4