Тэг ‘php’

SMF ошибки форума в таблице _log_errors

SMF (Simple Machines Forum) ведет лог ошибок, который сохраняет в базе в таблице _log_errors

2: strpos() [<a href=’function.strpos’>function.strpos</a>]: Offset not contained in string<br />Файл: smfdir/Themes/default/BoardIndex.template.php (eval?)<br />Строка: 1

2: gzinflate() [<a href=’function.gzinflate’>function.gzinflate</a>]: data error
Файл: smfdir/Themes/default/BoardIndex.template.php (eval?)
Строка: 1

2: strpos() [<a href=’function.strpos’>function.strpos</a>]: Offset not contained in string<br />Файл: smfdir/Themes/default/Register.template.php (eval?)<br />Строка: 1

8: Undefined index: dhhag
Файл: smfdir/Themes/default/BoardIndex.template.php (eval?)
Строка: 1

И еще куча записей с аналогичной ошибкой в разных файлах. Что-то подсказывает - видимо, “не все в порядке”..
Заглядываем в первую строку и видим что-то вроде:

<?php /**/eval(base64_decode('aWY ... 7fX19')); ?>

Подобное безобразие творится и в остальных “ошибочных файлах”. Файлы в одном каталоге, кстати имеют одинаковую дату изменения. Видимо имеет место, массовое изменение файлов по ftp или скриптом. Наблюдаем… Не исключено, что вирус на локальном компьютере.

upd 10.12.2009
После такой зачистки ошибки smf-форума довольно долго не появляются. Похоже, все в порядке.
Кстати, видимо, эта “зараза” поддерживает “обновления”. То есть при обновлении форума на более новую версию, она переносится (возможно, изменяясь) в файлы новой версии. И периодически “обновляется” - “зараженные” файлы имели довольно свежую дату изменения, причем в каждом каталоге свою и “одну на всех”…

Опубликовано Ноябрь 26, 2009 | автор: levik  |  Комментарии (2) »

Капча (captcha) для Wordpress

Думаю, сегодня, практически каждый, кто ведет свой блог на Wordpress, сталкивался со спам-комментариями. Комментируют все подряд, иногда даже “похоже, что в тему”, но все чаще - либо слишком общие фразы, либо вообще невпопад. :)

Как защититься от спамеров в комментариях?

Общепризнанный вариант - CAPTCHA (Капча, каптча) , от английского Completely Automated Public Turing test to tell Computers and Humans Apart (полностью автоматизированный публичный тест Тьюринга для различия компьютеров и людей).

В последнее время все чаще этим термином стали называть любую защиту от спама. Можно встретить сочетания “графическая капча”, “звуковая капча”. Не будем вникать в корректность этих словосочетаний.. Сделаем упор на защиту от спамера, неважно каким способом.

Плагины Капча для Вордпресс - краткий обзор / CAPTCHA for Wordpress

Капча yacaptcha

Yacaptcha

Плагин несложен в установке и довольно просто “разбирается” последовательность символов на картинке. Все-таки не нужно забывать о тех, кто будет вводить символы с клавиатуры.

Капча AntispamImage
Капча AntispamImage
Особенность состоит в том, что кроме изображения, присутствует еще и текст… Какие символы вводить, а какие - “пропустить”. Тоже довольно “разборчивый”.Особых сложностей в установке у меня не вызвал. :)

Капча “Клик и готово”

Один из “оригинальных” плагинов, который в силу своей оригинальности, простоты и удобства приобрел значительную массовость. Вся “фишка” заключается в том, что человеку нужно всего-лишь “кликнуть” на квадратик напротив надписи “Я не робот”. Надо отдать должное, и идея, и реализация - на высоте. А самое главное, он прост в изменении… На случай “взлома”..

Будем ждать, чем ответят спамерские скриптописатели…

Капча reCaptcha

Recaptcha - графическая и звуковая капча
Капча - монстр. :) Графическая и звуковая капча в “одном лице”. Причем, графические символы “не могут быть распознаны” обычным OCR алгоритмом. Однако, и человеку не всегда удается с первого раза распознать, о чем пишут.. И уж тем более, говорят (по-забугорному говорят.. )

Да, еще момент.. Много отзывов о проблемах с установкой плагина…

Simple CAPTCHA

Simple Captcha

Еще один пример графической капчи. Плагин устанавливается без проблем, работает “как часы”, однако, судя по отзывам, “взломан” спамерскими алгоритмами. Хотя, часть комментариев отсеивает - проверено. :)

Опубликовано Август 25, 2009 | автор: levik  |  Комментарии (10) »

Apache, htaccess и настройки PHP (php_value и php_flag)

Правильная (точнее, желаемая) работа PHP интерпертатора зависит от правильной конфигурации. Конфигурационные настройки PHP или директивы php.ini (php_value или php_flag) можно задавать несколькими способами:

  • в файле php.ini (скорее всего, если у Вас не выделенный сервер, то туда Вас не пустят. Хотя, некоторые хостинги предоставляют возможность создать собственный php.ini. Можно уточнить у хостинг-провайдера… Но в любом случае переживать пока рано, ведь это только первый способ;
  • если PHP используется как модуль Apache (или другого веб-сервера), то можно прописать настройки в файле httpd.conf (файл настроек веб-сервера, к которому пользователя простого хостинга тоже навряд ли допустят);
  • в файле .htaccess (в очередной раз речь про web-сервер, к примеру, Apache) - в последнее время обработка этого файла считается нормой для хостинга. И собственные настройки PHP, как правило, устанавливаются в этих файлах;
  • непосредственно в скриптах php с использованием функции ini_set().

Мы рассмотрели все возможные способы задания конфигурационных настроек интерпретатора PHP (Да, если кто знает другие варианты - сообщите.)

Есть еще маленькое “но”. Не все переменные php_value разрешено изменять в файле .htaccess (в зависимости от настроек сервера, изменение конфигурации PHP пользователем вообще может быть запрещено)

Некоторые настройки (:

php_value register_globals on
php_flag session.use_trans_sid off
php_flag session.use_only_cookies on
php_value max_execution_time 60
php_value upload_max_filesize 8M
php_flag display_errors off
php_flag log_errors on
php_value error_reporting 2047
php_value error_log log-file.txt

UPD шпаргалка по разрешениям изменений настроек PHP:
PHP_INI_USER = 1 значение может быть установлено в пользовательских скриптах
PHP_INI_PERDIR = 2 значение может быть установлено в php.ini, .htaccess или httpd.conf
PHP_INI_SYSTEM = 4 значение может быть установлено в php.ini или httpd.conf
PHP_INI_ALL = 7 значение может быть установлено где угодно

Ищем ошибки в PHP-скриптах (белый экран)
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);

Опубликовано Июнь 27, 2009 | автор: levik  |  Комментарий (1) »

locale и setlocale - устанавливаем локаль

Устанавливаем локаль.  памятка

setlocale(LC_ALL, ‘nl_NL’); // php4, 5

LC_ALL - все функции
LC_COLLATE - функции сравнения строк, см. strcoll()
LC_CTYPE - функции преобразования строк, например strtoupper()
LC_MONETARY - функция localeconv()
LC_NUMERIC - задает символ десятичной точки (см. также localeconv())
LC_TIME - форматирование дат функцией strftime()

Локали

ru_RU.UTF-8
ru_RU.CP1251
ru_RU.KOI8-R
en_US.UTF-8
ru_RU.KOI8-R
uk_UA.UTF-8
uk_UA.KOI8-U
uk_UA.CP1251
UTF-16/CP1251/CP866 (Windows)

В некоторых системах локали генерируются  только строчными буквами и без “минусов”-дефисов (несмотря на регистр при установке):

ru_RU
ru_RU.cp1251
ru_RU.iso88595
ru_RU.koi8r
ru_RU.utf8
russian
ru_UA
ru_UA.koi8u
ru_UA.utf8
Установить локаль (если прав хватит :))
localedef –no-archive -c -f CP1251 -i ru_RU ru_RU.CP1251

Опубликовано Июнь 11, 2009 | автор: levik  |  Комментарии (2) »

Ошибка PHP Strict Standards: date(), time() или date.timezone

[error] [client IP] PHP Strict Standards:  date() [<a href=’function.date’>function.date</a>]: It is not safe to rely on the system’s timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected ‘Europe/Moscow’ for ‘MSK/3.0/n
o DST’ instead in …

Иногда такими строками изобилуют логи ошибок web-сервера (apache тот же). В чем дело? Раньше ведь ошибок не было! Или были?… не помню…

Все дело в том, что в очередной версии php добавили timezone “по умолчанию”, которая используется в функциях даты-времени (date/time functions)

date.timezone “” PHP_INI_ALL Available since PHP 5.1.0.

Решается небольшой поправкой, которая “совместима” (звучит!) с предыдущими версиями php.

if (function_exists('date_default_timezone_set'))
date_default_timezone_set('Europe/Moscow');

Выдержка из List of Supported Timezones

Europe/Kiev
Europe/London
Europe/Minsk
Europe/Moscow
Europe/Riga
Europe/Samara
Europe/Simferopol
Europe/Tallinn
Europe/Tiraspol
Europe/Uzhgorod
Europe/Volgograd
Asia/Yekaterinburg
Asia/Novosibirsk
Asia/Krasnoyarsk
Asia/Irkutsk
Asia/Kamchatka
Asia/Magadan
Asia/Sakhalin

upd Для date.timezone в столбце Changeable стоит PHP_INI_ALL. Это означает установить её значение можно не только во время выполнения скрипта, но и в конфигурационных файлах:

- в .htaccess или httpd.conf следует добавить строку вида
php_value date.timezone "Europe/Moscow"

- в php.ini строку вида
date.timezone = Europe/Moscow

Опубликовано Май 28, 2009 | автор: levik  |  Комментарии (3) »

Водяные знаки на PHP

Проблема: иногда недобросовестные (или добросовестные, но без злого умысла и задней мысли) представители интернет-индустрии используют эксклюзивные авторские изображения без указания авторства и без всякого на то разрешения. Конечно, нормативные документы, гласящие об авторском праве в настоящее время упоминаются чуть ли не на каждом шагу; множество решений в суде, вынесенных в пользу автора…

Одним из способов указания авторства изображений, который довольно широко используется в Интернет - так называемые Watermark или Водяные знаки - изображения, содержащие информацию об авторе или сайте, для дальнейшего наложения на оригинальные авторские изображения.

В сети можно найти массу реализаций. Наиболее простым мне показался следующий вариант - наложение 8-битного (при желании - прозрачного) png-изображения (идентификатор в переменной $watermark_img_obj) с определенной прозрачностью ($alpha_level от 0 до 100) на основное изображение ($main_img_obj)

function watermark( $main_img_obj, $watermark_img_obj, $alpha_level = 100) {
$watermark_width = imagesx($watermark_img_obj);
$watermark_height = imagesy($watermark_img_obj);
$dest_x = imagesx($main_img_obj) - $watermark_width - 10; // правый
$dest_y = imagesy($main_img_obj) - $watermark_height - 10; // нижний угол изображения
imagecopymerge($main_img_obj, $watermark_img_obj, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, $alpha_level);
return $main_img_obj;
}

Конечно, это не “супер-мегакласс” с кучей параметров, но защитить изображения водяным знаком функция позволяет сделать без особых сложностей. Можно написать свою, как, например тут. Можно воспользоваться готовыми классами - watermark от PixelJeck-а, imagemanipulator, который предоставляет гораздо более широкие возможности для работы с изображениями, или же написать свой.

Еще, думаю, есть смысл обратить внимание на ImageMagic, а точнее на его интерфейс в php - IMagick.

Как лучше расположить надпись/водяной знак на изображении, чтобы с одной стороны сохранить информацию об авторе изображения, а с другой - не испортить изображение… Нельзя забывать, что желательно, чтобы посетитель мог сконцентрироваться не на водяном знаке, а на самом изображении.

Для Wordpress существует отдельный плагин wp-watermark, который кстати можно использовать для массового наложения водяных знаков на все файлы из каталога.

Любой класс или функцию можно взять за основу для своих наработок, которые в дальнейшем можно использовать как готовые “кирпичики” в своих проектах. Перерабатывая классы и функции “под себя” не только лучше вникаешь в алгоритм самой функции, но и можешь сделать то, что считаешь нужным. :)

Удачи!

UPD

http://darkair.livejournal.com/11583.html

Опубликовано Май 5, 2009 | автор: levik  |  Комментарий (1) »

CURL в PHP (libcurl)

CURL (Client URL Library), libcurl - библиотека функций для работы с серверами по различным протоколам (http, ftp, https … и ряд других - более подробно смотрите описание последней версии).

В php включена  (если точнее, имеется возможность включить - зависит от конфигурации сервера) поддержка curl. Проверить, поддерживается ли сервером функции curl проще всего, произведя вызов любой из функций, например
<?php
$ch = curl_init("http://www.example.com/");
?>

Если исполнение этого кода не приведет к ошибке - все в порядке, можем использовать CURL в “корыстных целях”. Если же “функция не существует”… Но, впрочем, это уже совсем другая история. А пока вернемся к нашим.. CURL ам.

В PHP самый простой вариант использования библиотеки обычно  сводится к следующим шагам:

Инициализация - curl_init($url);
Установка параметров - curl_setopt($ch, $opt, $value);
Выполнение запроса - curl_exec($ch);
// Получение и обработка информации - обычно хватает результата, возвращенного предыдущей функцией, однако, существует несколько дополнительных функций, например curl_getinfo($ch);
Закрытие - curl_close($ch);

Особенности и подводные камни:
CURLOPT_COOKIEFILE и CURLOPT_COOKIEJAR при работе в  WINDOWS будут правильно работать только при указании полного пути к файлу.

curl_setopt($ch,CURLOPT_COOKIEFILE,dirname(__FILE__).’/tmpfile.txt’;)

php class Snoopy позволяет использовать php почти как браузер - скачиваем, загружаем…

Опубликовано Апрель 7, 2009 | автор: levik  |  Нет комментариев »

И снова бланки - работа с word средствами javascript и php

В очередной раз стала актуальной задача с подготовкой бланков. Однако, способ с бланком в формате rtf не подходит - файл .doc весит ~2 Мб, файл же rtf ~ 34 Мб. Видимо, зависит от хранения рисунков…

Работать с COM-объектом Word можно непосредственно из PHP:

// Код PHP
$word=new COM("Word.application") or die("Couldn't start Word!");
//после создания объект невидимый
//сделаем его видимым и активизируем (разумеется, для работы на сервере это необязательно)
$word->visible =1;
$word->Activate();
//Создать документ по шаблону:
$word->Documents->Add("c:\\template.dot");
// действия - найти-заменить и т.д. Описаны в документации по VisualBasic for Application - в справке MS Word (по умолчанию не устанавливается)
$word->ActiveDocument->SaveAs("C:\\".$fname);
$word->Quit();

Однако, подобный способ подходит только для Windows-серверов.

Еще один вариант - работа с COM-объектом на стороне клиента через Active-X при помощи JavaScript:


><script language="javascript">
// Создание объекта MS Word:
word = new ActiveXObject ("Word.Application");
// Создание документа и установка параметров страницы:
with (word) {
Documents.Open('c:\\0.doc');
ActiveDocument.Label1.Caption = < ?=$sum?>;
ActiveDocument.SaveAs ('c:\\1.doc');
Quit (); // завершает работу MS Word
}
</script>

Предварительно следует сохранить документ-шаблон на диск C:\ с именем 0.doc.
В шаблоне - создать “Label”-ы и расположить их в соответствии с нужным расположением текста.
С учетом специфики задачи - получаем еще один небольшой выйгрыш - “основной” файл не качается с сервера.
Технология, думаю, понятна. Вариации - насколько фантазии хватит.

ps. Не забудьте поставить разрешения в свойствах обозревателя.

( Свойства обозревателя - безопасность - Выбираем “Надежные узлы”. После чего, нажимаем “Другой..” - и устанавливаем все переключатели, где упоминается ActiveX в “Разрешено”.)

А в Надежные узлы следует добавить “Наш” сайт - где формируются бланки.

Опубликовано Март 18, 2009 | автор: levik  |  Нет комментариев »

HTTP заголовок - как передать?

Вебмастеру частенько нужно передать служебную информацию при помощи HTTP-заголовка. Как это можно сделать?

Передаем Http заголовок средствами HTML

Если быть совсем точным, то формулировка не совсем верна, поскольку мы передаем не заголовок, а служебную информацию, аналогичную информации заголовка, однако содержится она непосредственно в сообщении. Однако, META-теги, например могут влиять на кэширование страниц в браузере по аналогии с HTTP-заголовками.
<meta http-equiv=”Expires” content=”Mon, 19 Jan 2009 20:37:25 GMT”>
<meta http-equiv=”Pragma” content=”no-cache”>

Передаем HTTP-заголовок средствами PHP

В PHP (да и в любом серверном языке программирования) для передачи заголовков существует специальная функция. В PHP она носит название header(). В качестве параметра указывается текст http-заголовка:
header('Content-Language: ru');
header("HTTP/1.0 404 Not Found");
// далее следует вывод страницы
?>

Следует отметить, что  вывод заголовков должен предшествовать выводу содержимого документа. Иначе, php-интерпретатор выдаст предупреждение, а заголовок передан не будет.

Передаем HTTP-заголовок средствами сервера

Часть заголовков формируется без явного указания в скрипте, непосредственно сервером или его модулями (например, php-интерпретатор сообщает заголовок “X-Powered-By”). Мы можем подсказать серверу, какие заголовки выдавать в том или ином случае.

В частности, Apache-сервер позволяет формировать HTTP-заголовки при помощи служебного файла .htaccess
Header set Cache-Control “no-cache, must-revalidate”
Header set Expires “Mon, 19 Jan 2009 20:41:25 GMT”
Header set Pragma “no-cache”

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

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

Опубликовано Январь 19, 2009 | автор: levik  |  Комментарий (1) »

Регулярные выражения в PHP - как найти первое вхождение конца или убираем жадность

Регулярные выражения - сложный на первый взгляд, но удивительно мощный инструмент. Подробное описание синтаксиса регулярных выражений занимает не одну страницу.

Иногда требуется выудить содержимое, заключенное в заранее известные границы. Но как быть, если “последняя” граница не единственная в документе? А при попытке выбрать все совпадения почему-то используется не первое вхождение маски, а последнее. Т.е., при попытке выбрать содержимое всех элементов div1 примерно таким кодом:

preg_match_all ('/<div class="div1">(.*)<\/div>/is', $text,$matches) // где текст содержит следующий код:

<div class=”div1″>
<a href=”href0-1″><img src=”image0-1.jpg”></a>
<a href=”href0-1″><img src=”image0-2.jpg”></a>
<a href=”href0-1″><img src=”image0-3.jpg”></a>
</div>

<div class=”div1″>
<a href=”href1″><img src=”image1.jpg”></a>
</div>
<div class=”div1″>
<a href=”href2″><img src=”image2.jpg”></a>
</div>

Мы получим не три значения, а всего одно, в котором будет всё от первого <div class=”div1″>  до последнего </div> - т. е. практически весь код, кроме самих тегов.

Чтобы получить как задумано массив из трех элементов, достаточно добавить модификатор “нежадности” - Ungreedy:

preg_match_all ('/<div class="div1">(.*)<\/div>/isU‘, $text,$matches)

UPD PHP (в Perl такой функциональности не предусмотрено) Если потребуется внутри такого шаблона задать “жадную” подстроку - добавляем “?” к этой подстроке:
чтобы в примере выудить image0-3.jpg из каждой строки, используем маску /src=”([^”]+?)/is - без символа вопроса будет задействован только первый символ. При добавлении вопроса устанавливается “жадность” - ищем, пока не найдем кавычку. (можно, конечно воспользоваться чем-то вроде /”([^”])”/, но идея - показать “местную” жадность )

Опубликовано Ноябрь 3, 2008 | автор: levik  |  Комментарии (2) »