Архив метки: PHP

PHP + PDO + SQL Server + SQL-запрос LIKE = возможные проблемы

Если у вас возникает ошибка

SQLSTATE[IMSSP]: Tried to bind parameter number 0.  SQL Server supports a maximum of 2100 parameters.

при запросе типа

SELECT * FROM table_name WHERE name LIKE 'nick'

с использованием подготовленного SQL-запроса в PHP PDO на сервер БД Microsoft SQL Server, то знайте в чем беда: функция prepare() уже сама проставит все кавычки и отметки (юникод или ASCII), за неё это не следует делать. А теперь конкретный пример: есть запрос SELECT * FROM table_name WHERE name LIKE ‘%<something>%’ Дабы использовать всю мощь PDO в борьбе с SQL-инъекциями следует использовать методы prepare и execute. Как это делать неправильно:


$sql = "SELECT * FROM table_name WHERE name LIKE N'%:name%'";

$db = new PDO("...");

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // catch error via normal "try ... catch"

$statement = $db->prepare($sql);

$statement->execute(array(':name' => 'Наташа'));

Казалось бы, всё правильно. Мы поставили символ N в $sql, который говорит SQL Server, что поиск пойдет по тексту в кодировке юникод, обрамили сам запрос в кавычки. Но нет! Лезут ошибки. А дело оказалось в том, что prepare() сам уже проставит всё, что нужно. Таким образом правильный код выглядит следующим образом:


<strong>$sql = "SELECT * FROM table_name WHERE name LIKE :name";</strong>

$db = new PDO("...");

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // catch error via normal "try ... catch"

$statement = $db->prepare($sql);

<strong>$statement->execute(array(':name' => '%Наташа%'));</strong>

Помог ответ на этот вопрос (хотя там ошибка другая у товарища). И еще, после дочитал-таки официальный ман по теме и оказалось в последнем примере как раз говорится о такой ошибке. В общем, вся сложность в её выявлении оказалось в неадекватном сообщение об ошибке в SQL Server.

ModX на Linux + удаленный Microsoft SQL Server ? love

Так вышло, что надо было реализовать следующую конфигурацию:

Linux (Debian) + Apache + PHP + ModX revolution + удаленный MS SQL Server

Сначала я попробовал решить задачу «в лоб», но процесс установки на первых же этапах выдавал ошибку без комментариев. После пары часов гуглинга я понял, что у такой конфигурации просто нет будущего по следующим причинам:

  1. ModX 2.1+ использует Microsoft SQL драйвер для PHP (это набор функций типа sqlsrv_*). Однако этот драйвер был выпущен только для Windows платформы. Будущий релиз на Linux крайне туманен.
  2. Есть возможность использовать открытый драйвер  FreeTDS, но тогда придётся все функции типа «mssql_*» переназначить на функции «sqlsrv_*«. Некоторые ребята сделали подобный трюк для Drupal, но при этом отмечалась общая нестабильность конфигурации и работало это только для MS SQL Server 2008.

Хорошо, что заказчик согласился сменить конфигурацию, и сейчас ModX отлично работает на Windows Azure (облачный IIS + MSSQL).

Moodle 2.2+: настраиваем регистрацию по электронной почте

Краткое содержание:

  1. Включение отправки сообщений Moodle’ом по почте пользователям
  2. Включение самостоятельной регистрации по почте
  3. Упрощение требований к паролю при регистрации
  4. Включение самостоятельной свободной записи на курс для зарегистрированных пользователей

Проблема: в Moodle не используется стандартная функция отправки почты в PHP – mail(). Вместо этого предлагается использовать для отправки системой сообщений о подтверждении самостоятельной регистрации по почте через почтовые сервера по протоколам SMTP, IMAP или ряде других.

Решение: настроить почту, используя бесплатный GMail по протоколу SMTP. Для этого:

  1. Заходим на  http://gmail.com и регистрируем почтовый ящик, например, bob@gmail.com с паролем 12345
  2. Входим в систему Moodle в качестве администратора.
  3. В левом меню выбираем «Администрирование -> Плагины -> Message outputs -> Manage message outputs«
  4. Включаем электронную почту, нажатием на глаз напротив соответствующей строки.
  5. Выбираем «Настройка» напротив Электронной почты.
  6. В графе SMTP-серверы пишем  ssl://smtp.gmail.com:465
  7. В графе Логин SMTP – адрес зарегистрированной электронной почты в GMail. В нашем примере вписываем bob@gmail.com
  8. В графе Пароль SMTP – пароль зарегистрированной почты. В нашем примере это 12345
  9. Остальные настройки не трогаем и жмем внизу на «Сохранить изменения».

Регистрация в системе по электронной почте

Небольшая инструкция, как включить регистрацию по электронной почте:

  1. В левом меню выбираем «Администрирование -> Плагины -> Аутентификация -> Настройка аутентификации«
  2. Включаем «Самостоятельная регистрация по электронной почте» (нажатием на закрытый глаз).

Упрощение требований к паролю при регистрации

И на десерт – изменяем формата вводимого пароля при регистрации. По умолчанию он слишком сложный: надо и спец-символ вставить, и чтобы большие буквы были, и маленькие, и еще цифры! Ужас!) Так что давайте облегчим жизнь пользователям и сделаем требования по-проще: от 6 символов в пароле и… всё!) Т.е. в пароле могут быть или просто цифты или просто буквы, в общем, что угодно:

  1. Администрирование -> Безопасность -> Политика безопасности сайта
  2. Находим графу Длина пароля и вводим там 6
  3. В графах Цифр, Букв в нижнем регистре, Букв в верхнем регистре и Не буквенно-цифровых символов вводим 0
  4. Жмем Сохранить изменения

Включение самостоятельной записи на курс

И раз уж такая волна, разбемся, как включить самостоятельную запись на курс:
  1. Создаем курс
  2. Включаем Режим редактирования курса (в левом меню)
  3. Управление курсом -> Пользователи -> Способы записи на курс (все в том же левом меню)
  4. В выпадающем меню Добавить способ выбираем Самостоятельная запись
  5. Настройки по умолчанию вполне нормальны, поэтому сразу жмем Добавить способ

Поиск по русским буквам в mysql (проблема "е" и "ё" в utf-8)

Была задача найти все слова, начинающиеся на определенную букву. Казалось бы, что может быть проще?)

Стоит отметить, что сайт на utf-8, таблицы в utf8_general_ci. Начал я с простого: для передачи ссылка (с GET запросом для сортировки по определенной букве, типа «http://sky2high.net/sort.php/?letter=Ю«) проходила через php-ое urlencode(), а на приеме через urldecode(), на выходе которого получаем необходимую букву.

Сначала скрипт выборки из БД был типа такого:

SELECT name, lat_name, video
FROM ru_words AS w
WHERE w.name LIKE "{$letter}%"
ORDER BY w.name

И всё бы хорошо, но БД выдавала одинаковые результаты для букв «е» и «ё». Тут я и впал в ступор, стал гуглить. Оказалось, что это ошибка mysql-server-5.0.xx, рекомендовали апгрейдить на 5.1 (а на боевом сервере стоит mysql 5.0.xxx), что, конечно, есть большой геморр, особенно в виду отсутствия deb-пакетов для ubuntu 8.04 LTS, что значит надо собирать из исходников, заново настраивать, импортировать БД и т.д..

Далее, вспомнил про прекрасный оператор REGEXP в SQL запросах (и правильно сделал! — прим. КО), однако запрос типа

SELECT name, lat_name, video
FROM ru_words AS w
WHERE w.name REGEXP "^{$letter}"
ORDER BY w.name"

Не дал результатов, то есть вообще никаких, слова перестали находится. Не знаю зачем (ведь перед глазами постоянно мелькало из документации «REGEXP ведет НЕ РЕГИСТРОЗАВИСИМЫЙ поиск»), но всё-таки попробовал передать в запросе поиск не по заглавной букве, но по прописной.

$letter = mb_strtolower((urldecode($letter), 'UTF-8')

И мини-чудо озарило мой экран: поиск стал просто идеально идти по всем буквам.

Выводы: даже и не знаю какие. Доверять, конечно, надо документации, но и проверять.

eAccelerator

Поставил на этот сервер php eAccelerator 0.9.6 rc1: скорость работы отдельных скриптов увеличилась почти в 10 раз.
Всем рекомендую.)

Небольшой tip:

В php.ini надо будет вносить некоторые параметры чтобы подключить и настроить eAccelerator. После установки из сырцов (make install) вам высветится что-то типа такого:


# make install
Installing shared extensions: <strong> /usr/lib/php5/20060613/

Именно эту папку и надо будет указывать в php.ini в строке

zend_extension = "/usr/lib/php5/20060613/eaccelerator.so"

Я думаю, многие и так догадаются, но тем не менее в распространенных туториалах указывается другая папка и вообще этот момент опущен.