Записки самоучки

28 мая, 2007

Танцы с бубнами вокруг настройки сервера Windows 2003+Apache 2.2.4+PHP 5.2.2+MySQL 5.0.41

Filed under: Apache,Глюки,MySQL,PHP — 4matic @ 4:56 пп

Занимался настройкой веб-сервера. Давно не тратил столько времени на настройку!

Все сделал как обычно. Скачал свежие релизы. Установил каждый из продуктов. Начал настраивать совместную работу. И тут началось веселье.

При попытке установить расширения для работы с СУБД  получилось вот что. расширение для работы с MSSQL встало без капризов, а вот при попытке подключить расширение mysqli получил ошибку invalid access to memory location. Не буду рассказывать о всех танцах с бубнами на протяжении 4 часов, просто расскажу, в чем проблема и как решил.

Имею привычку разворачивать PHP и прописывать PHPRC=»C:\PHP\» в системных переменных окружения. И потом все подключаемые библиотеки хранить в  C:\PHP\. Так вот после гугиления нашел на одном форуме скромное замечание о том, что не смотря на то, что в документации PHP предлагает делать те действия, которые я и выполнил, в некоторых релизах Windows подключение библиотек для работы PHP по путям отличным от C:\Windows или C:\Windows\System32 происходит некорректно. Почему — этого науке не известно.

Как решил проблему. Просто перекинул файлы libmysql.dll и php5ts.dll в папку C:\Windows\System32 и проблема почти решилась. Почти, потому что возникили еще одни грабли. Имею привычку (дурную???) использовать libmysql.dll не из релиза PHP, а из релиза MySQL. Так вот, клиент от MySQL не захотел подключать расширение mysqli, а родной PHP-шный запустился без проблем. Т.е. пришлось в папку C:\Windows\System32 кидать libmysql.dll, которая шла вместе с PHP, а не MySQL.

P.S. Неприятно, что после того, как MySQL перестал оперативно выпускать бинарники для Windows, вообще перестали обновлять библиотеки API PHP.

6 февраля, 2007

WordPress 2.1 с поддержкой mysqli

Filed under: Движки,MySQL,PHP — 4matic @ 2:56 дп

У меня свой сервер. На нем поднят Apache и PHP 5.2.0. Так же есть сервер MySQL 5.0.27. У PHP стоят только те расширения, что мне нужно. В частности мне не нужно расширение mysql, но мне нужно расширение mysqli. Владея такой конфигурацией решил поставить Worpdress. К своему удивлению обнаружил, что WordPress не знает ничего о расширении mysqli. Так же есть пробелы при описании классов. В частности, при описании классов не описаны все поля класса, что для версий PHP5 не есть правильно. Но это на самом деле мелочи. Ниже я опишу процесс подключения поддержки расширения mysqli. Благодаря архитектуре WordPress, не составит большого труда наладить работу и с другими СУБД.

  1. Идем в директорию wp-includes. Делаем копию файла wp-db.php и даем копии имя db.php. Копию кладем в туже директорию, что и wp-db.php.
  2. Открываем файл и правим в нем все функции mysql_* на соответствующие им функции mysqli_*. При этом не забываем, что нужно обязательно указывать идентификатор ресурса результата запроса. Кстати, этот идентификатор не описан в классе. Поэтому выполняем пункт 3.
  3. Описываем в классе забытое, но нужное свойство $dbh, добавляя строку var $dbh где-то в районе дислокации всех var класса wpdb.
  4. Что-то какие-то непонятки с экранированием строк, которые поступают в запросы. Из-за каких-то непонятных мне причин разработчики решили просто прослешивать функцией addslashes():

    function escape($string) {
    return addslashes( $string ); // Disable rest for now, causing problems
    if( !$this->dbh || version_compare( phpversion(), ‘4.3.0’ ) == ‘-1’ )
    return mysql_escape_string( $string );
    else
    return mysql_real_escape_string( $string, $this->dbh );
    }

    Я вместо этого написал:

    function escape($string) {
    return mysqli_real_escape_string($this->dbh, $string);
    }

  5. Сохраняем изменения, закрываем файл. Или качаем db.php.
  6. Идем в директорию wp-admin.
  7. Делаем копию файл upgrade-functions.php и называем ее upgrade-ifunctions.php.
  8. Открываем upgrade-ifunctions.php и изменяем функцию:
  9. function wp_check_mysql_version() {
    global $wp_version;

    // Make sure the server has MySQL 4.0
    $mysql_version = preg_replace(‘|[^0-9\.]|’, », @mysql_get_server_info());
    if ( version_compare($mysql_version, ‘4.0.0’, ‘<‘) )
    die(sprintf(__(‘<strong>ERROR</strong>: WordPress %s requires MySQL 4.0.0 or higher’), $wp_version));
    }

    на

    function wp_check_mysqli_version() {
    global $wp_version;
    global $wpdb;

    // Make sure the server has MySQL 4.0
    $mysqli_version = preg_replace(‘|[^0-9\.]|’, », @mysqli_get_server_info($wpdb->dbh));
    if ( version_compare($mysqli_version, ‘4.0.0’, ‘<‘) )
    die(sprintf(__(‘<strong>ERROR</strong>: WordPress %s requires MySQL 4.0.0 or higher’), $wp_version));
    }

    Так же в этом файле поменяйте вызовы функции wp_check_mysql_version() на wp_check_mysqli_version() (2 раза).

  10. В директорию wp-admin находим файл setup-config.php и меняем в нем строку (у меня строка 154):

    require_once(‘../wp-includes/wp-db.php’);

    на:

    if ( file_exists(ABSPATH . ‘wp-content/db.php’) )
    require_once(‘../wp-includes/db.php’);
    else
    require_once(‘../wp-includes/wp-db.php’);

    Т.е. теперь, при наличии файла db.php — нашего враппера (обмертки) запросов к СУБД, WP попробует подключить его, а если не найдет этот файл, то подключит стандартный врапер, к которому и пальцем не прикасались.

  11. В той же директории находим файл install.php и меняем в нем строку (у меня строка 9):

    require_once(‘./upgrade-functions.php’);

    на:

    if ( file_exists(ABSPATH . ‘wp-admin/upgrade-ifunctions.php’) )
    require_once(ABSPATH . ‘wp-admin/upgrade-ifunctions.php’);
    else
    require_once(ABSPATH . ‘wp-admin/upgrade-functions.php’);

    Т.е. теперь, при наличии файла upgrade-ifunctions.php — «нашего файла», WP попробует подключить его, а если не найдет этот файл, то подключит стандартный файл upgrade-functions.php, к которому и пальцем не прикасались.

  12. В той же директории находим файл admin.php и меняем в нем строку (у меня строка 92):

    require_once(ABSPATH . ‘wp-admin/upgrade-functions.php’);

    на:

    if ( file_exists(ABSPATH . ‘wp-admin/upgrade-ifunctions.php’) )
    require_once(ABSPATH . ‘wp-admin/upgrade-ifunctions.php’);
    else
    require_once(ABSPATH . ‘wp-admin/upgrade-functions.php’);

  13. В той же директории находим файл upgrade.php и меняем в нем строку (у меня строка 8):

    require_once(ABSPATH . ‘/wp-admin/upgrade-functions.php’);

    на:

    if ( file_exists(ABSPATH . ‘wp-admin/upgrade-ifunctions.php’) )
    require_once(ABSPATH . ‘wp-admin/upgrade-ifunctions.php’);
    else
    require_once(ABSPATH . ‘wp-admin/upgrade-functions.php’);

    Кстати, обратите внимание, что лишний слеш, потому что ABSPATH заканчивается слешем, а тут еще один прицепили.

  14. Последний рывок. Идем в корневую директорию распакованного движка, открываем файл wp-settings.php, находим строку (у меня строка 100):

    require_once (ABSPATH . WPINC . ‘/wp-db.php’);

    на:

    if ( file_exists(ABSPATH . ‘wp-includes/db.php’) )
    require (ABSPATH . ‘wp-includes/db.php’);
    else
    require_once (ABSPATH . ‘wp-includes/wp-db.php’);

Если я ничего не забыл, то все готово для инсталяции WordPress на сервере с конфиграцией PHP5 с расширением mysqli, но без расширения mysql, а так же самой СУБД MySQL. Если что-то упустил — комментируйте, но сначала попробуйте отладить самостоятельно!

P.S. Отредактированные файл выложить не могу — не позволяют настройки WordPress.

Предупреждение. Если вы выделяете и копируете тексты из блога, то исправляйте кавычки. В блоге кавычки обратные и скрипт с такими кавычками корректно работать не будет!!!!!

26 января, 2007

Хранимые процедуры в MySQL. Ссылки на ресурсы

Filed under: Ссылки,MySQL — 4matic @ 6:35 пп

До сегодня не работал с хранимыми процедурами. Вот, сегодня поработал с хранимыми процедурами в MS SQL. Очень понравилось. Я уже давно сижу на ветке 5.0.*, но разбираться с ХП было лень, да и русской документации или статей по ХП я не встречал. Мой ужасный английский так же не способствует активному изучению. Но сегодня собрал волю в кулак и подтянул теоретические занния о хранимых процедурах в MySQL, а заодно и по английскому языку. Вот достаточно толковые ссылки по теме:

MySQL 5.0 New Features: Stored Procedures  — в конце текста страницы есть ссылка на обзорную, но подробную документацию по хранимым процедурам и функциям в MySQL 5.

Stored Procedures in MySQL 5.0 — интересный (хоть и небезопасный) подход к созданию процедур. Думаю, что для общего развития будет полезно узнать о принципе создания.

MySQL Series — раздел «MySQL Stored Procedures and Functions». На реальных примерах даются общие понятия о хранимых процедурах и функциях. Обратите внимание на то, что статьи разбиты на две страницы (я сначала думал, что страницы — это части).

Ну, и на закуску — святое. Документация по MySQL.

SQL Syntax for Prepared Statements

Stored Procedures and functions

Если представится возможность, то попробую протестировать решения с помощью ХП и без ХП (логика перенесена на клиента PHP) .

P.S. По аське прислали перевод классической хакерской фразы «Just unzip. Run. Enjoy!». Перевод: «Расстегните молнию. Бегите. Получайте удовольствие!».

P.P.S. Удачных выходных!

22 января, 2007

MySQL постепенно перестает быть Open Source

Filed under: Это жизнь,MySQL — 4matic @ 3:22 пп

Я что-то проспал. А уже достаточно давно наметились неприятные тенденции в политике MySQL.

Некоторые активные участники MySQL сообщества относятся к нововведениям с частичным пониманием, но не принимают политику до конца.

Например:

Things Ain’t What They Used To Be

MySQL Binaries availability

Кому нужен свежий бинарник для Windows, идем, например, сюда, забираем свежий (5.0.33) релиз в бинаре и говорим спасибо SQLyog.

P.S. Неприятно наблюдать подобные вещи.

P.P.S. Текущее состояние вещей с Mysql считаю банальное жлобством.

P.P.P.S Надо научиться, как из исходников делать бинарники.

Update: Хорошая ссылка http://discuss.joelonsoftware.com/default.asp?biz.5.439544.51

10 января, 2007

Проблема с кодировками в MySQL

Filed under: Ссылки,MySQL — 4matic @ 11:32 дп

В продолжение моей темы кодировок, выкладываю список ссылок на ресурсы, которых достаточно для того, что бы устранить проблемы с кодировками.

  1. My SQL 4.1+ и любые проблемы с русскими буквами — на мой взгляд, это самая полная рускоязычная статья о проблемах с кодировками. (http://phpclub.ru)
  2. Если у вас MySQL 4.1 и любые проблемы с русскими буквами, то загляните вначале сюда! — топик форума по кодировкам MySQL ресурса из предыдущего пункта. Есть несколько освещённых практических моментов и граблей. (http://phpclub.ru)
  3. Проблема с кодировками в MySQL — достаточно подробный топик форума, в котором расписано, как правильно настраивать подключения и работать с кодировками. (http://php.com.ua)
  4. Chapter 10. Character Set Support и 5.11. MySQL Localization and International Usage — RTFM никто не отменял. Ссылки на разделы документации, в которых расписана работа с кодировками в MySQL. (http://mysql.com)

Совет №1. Если вы первый раз услышали о кодировках, то начните с понимания терминов: «кодировка», «набор символов», «юникод» и т.д. Начните например с Википедии.

Совет №2. Хотите задать вопрос на форуме о проблемах с кодировками, то формулируйте его на основании знаний полученных из озвученных выше источников. Цитируйте конкретные непонятные вам моменты прочитанных статей. Приводите скрипты (настройки сервера, переменных окружения) и результаты экспериментов с кодировками. Иначе в 99 случаях из 100 вас пошлют RTFM или в Google — правильно сделают.

Совет №3. Если вы поглатили всю информацию, а проблему не смогли решить, значит вам нужно перестать работать с СУБД, а заняться, например вязанием.

И ещё раз повторюсь. Информации по приведенным выше ссылкам достаточно, что бы корректно работать с кодировками MySQL. Полное понимание того, что вы делаете придёт со временем.

14 декабря, 2006

На сайте MySQL лучше пользоваться поиском Google

Filed under: Это жизнь,Google,MySQL — 4matic @ 11:40 пп

Столкнулся с проблемой при работе с GUI Tools от MySQL. Зашел на сайт разработчика, прошелся по багрепорту, а затем штатным поиском по сайту. За релевантность полученной информации можно смело забыть. Выдает все подряд и в большом количестве. Зашел в Гугл и просто ввел ту же фразу, по которой искал штатным поиском. Первая же ссылка оказалась то, что нужно: на сайт MySQL на нужную страницу.

11 ноября, 2006

Изменение кодировки таблиц в MySQL

Filed under: MySQL — 4matic @ 12:17 дп

Начиная с версии 4.1 ,СУБД MySQL умеет работать с кодировками. Для многих работа с кодировками в MySQL — это большая проблема. Проблемы, связанные с кодировками неплохо освещены в Википедии на сайте http://phpclub.ru. Тем, кто плавает в вопросах кодировки я рекомендую посетить ресурс и читать статью до полного понимания. В основном в статье освещаются проблемы, связанные с настройкой связки PHP vs MySQL. Главное, что нужно запомнить, что кодировка содержимого БД и кодировка соединения должны совпадать. Ну, мы немного отклонились от темы.

Итак, все началось с того, что вы установили MySQL, создали таблицы, наполнили их данными, а потом обнаружили, что запросы к таблицам, в которых есть поиск или сортировка по полям типа CHAR, VARCHAR, TEXT выдают непредсказуемые результаты. Если это происходит, то, скорее всего, у вас некорректно указаны кодировки для данных. Попытаюсь объяснить, в чем проблема. Надеюсь, вы понимаете, что такое кодировка. Если нет, то прогугилите вопрос и получите хотя бы первичные знания.

Итак. Проследим, как получилось так, что у вас появились проблемы с кодировкой. MySQL при установке по умолчанию указывает кодировку для БД latin1. Большинство клиентов, при подключении, настроены на кодировку latin1. Вы, пользуясь клиентами, вносите данные, просматриваете результаты и т.д. При этом везде используете кодировку latin1. Эта кодировка позволяет корректно отображать кириллицу. На этом корректность в работе с кириллице в кодировке latin1 заканчивается. Cимволы вы видите правильные, но коды в таблице символов в данной кодировке не соответствуют реальным кириллическим символам. И получается, что поиск и сортировка выдают непредсказуемые результаты, потому что работа происходит не с символами, которые вы видите, а с кодами. Может, запутано объяснил, тогда ставлю перед фактом: кодировка latin1 — это некорректная кодировка для полноценной работы с криллицей. Для корректно работы с кириллицей нужно выбирать кодировки, которые поддерживают кириллицу. Для того, что бы узнать полный список этих кодировок RTFM по MySQL. Я же остановлюсь на двух распространённых из них: utf-8 и cp1251. Начну с cp1251, потому что это родная кодировка для ОС Windows.

Итак, перед нами стоит задача: конвертировать данные, из изначально некорректно заявленной кодировки latin1 в корректную кодировку cp1251. Идем в документацию по языку:

If you want to change the table default character set and all character columns (CHAR, VARCHAR, TEXT) to a new character set, use a statement like this:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name; (1)

Не спешим выполнять предложенное решение, а читаем дальше:

Warning: The preceding operation converts column values between the character sets. This is not what you want if you have a column in one character set (like latin1) but the stored values actually use some other, incompatible character set (like cp1251). In this case, you have to do the following for each such column:
ALTER TABLE t1 CHANGE c1 c1 BLOB; (2)
ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET cp1251; (3)

The reason this works is that there is no conversion when you convert to or from BLOB columns.

Простое конвертирование данных (1) нам не подходит, потому что у нас некорректные коды для символов, а так как конвертирование происходит согласно таблице кодов, то мы получим некорректный результат. Выход в данной ситуации — это избавиться от привязки символов к кодировке. Это делается путем преобразования данных и символьного типа в двоичные данные (2). Представьте, что кодировка — это маска, которая накладывается на двоичные данные. Т.е. сам порядок байтов не изменяется, а изменяется только маска, по которой выбираются коды для визуального формирования символов. Итак, запросом (2) вы избавились от маски, а запросом (3) вы применили новую маску. Повторюсь еще раз (грубо говоря): физически мы не изменили ни одного байта данных, мы изменили правило формирования символов! В итоге вы получаете следующее: сами данные как были корректными для кодировки cp1251, так они и остались, но теперь мы правильно указали кодировку cp1251.

После таких манипуляций жизнь вашей БД и выборок должна наладиться, потому что теперь все сходится и все на своих местах. Теперь, если вы захотите изменить кодировку таблицы и полей, то можете смело пользоваться запросом (1). Кстати, я сейчас думаю переходить с cp1251 на utf-8, но пока что не могу чётко озвучить, зачем мне это надо: кое-какие предпосылки есть, но ясного понимания пока что нет.

Замечания:

  1. Если вы конвертируете данные, из изначально некорректно заявленной кодировки latin1 в корректную кодировку cp1251. Нельзя просто взять и изменить кодировку для столбца, т.е. не выполнять запрос (2), а сразу выполнить запрос (3). Потому что выполнив сразу запрос (3) мы физически не перестроим маску, а просто изменим текущее значение маски. Если у вас нет проблем с несоответствием кодировок, и вам нужно просто поменять кодировку таблицы, то вам нужно всего-навсего выполнить запрос (1).
  2. Если вы конвертируете данные, из изначально некорректно заявленной кодировки latin1 в корректную кодировку cp1251. При этом вы изменяете кодировку у поля, у которого есть индексы, то перестройте индексы (удалите и создайте заново).
  3. Если вы решите переходить на кодировку utf-8 — проверьте, что бы визуальные клиенты поддерживали unicode. Например, так горячо мною любимый SQLyog 5.2 курит бамбук при отображении содержимого таблиц, хранящих данные в utf-8.
  4. MySQL начал поддерживать unicode только с версии 4.1.x, т.е. до этого поддержки юникода не было. Это значит, если вы захотите перенсти таблицы с юникодом на версию младше 4.1.x, то у вас ничего не получится. Выходов два: или конвертировать данные из юникода во что-то менее многобайтовое, например, cp1251; или обновлять СУБД до версии не младше 4.1.x. Обновление СУБД предпочитетльней, потому что у MySQL уже 3ка по-моему не поддерживается и 4ка тоже скоро перестанет поддерживаться, при этом активно 5ка в двух ветках разрабатывается. Да и весь мир в юникоде активно в сети работает.

23 августа, 2006

Отображаемые опции в MySQL Administrator можно настраивать

Filed under: Глюки,MySQL — 4matic @ 6:26 пп

Возможно моя заметка для кого-то не станет новостью, а вызовет фразу «Документацию по продукту нужно читать«. Хотя, как вариант, мое маленькое открытие будет интересно тем, кто часто экспериментирует с настройками сервера СУБД MySQL.

Надцать дней тому назад я отправил bugreport о работе с MySQL Administrator. Суть проблемы сводилась к следующему. Некоторые настройки сервера не доступны через интерфейс программы — поэтому эти настройки нужно указывать ручками в my.ini. Далее, когда мы открываем MySQL Administrator и правим через интерфейс программы другие настройки сервера. Затем сохраняем изменения, при этом: те настройки, которых нет в интерфейсе программы — комментируются. Возможно сумбурно описал, но надеюсь, что все понятно или станет понятно, когда прочтете bugreport.

Сегодня я получил сообщение о варианте решения проблемы. Оно оказалось оригинальным и познавательным. Оказывается, за интерфейс программы отвечают xml-файлы, которые лежат в директории <путь, куда инсталлирована программа>/xml/. В моей ситуации нужно было редактировать файл mysqladmin_startup_variables_description.xml. Принцип работы с файлами достаточно просто и понятен — достаточно открыть файлы и подумать. Редактируя содержимое xml-файла, вы можете управлять отображением настроек сервера СУБД в интерфейсе MySQL Administrator. Я без проблем добавил нужную мне настройку, и после этого настройка перестала комментироваться.

Спасибо Vladimir Kolesnikov, который подсказал вариант обхода комментирования. Но сама проблема так и не решена. Понятно желание разработчиков GUI уберечь файл конфигурации от ошибок, но комментирование корректных настроек сервера только потому что их нет в GUI — это неправильно.

P.S. Перед тем как редактировать файлы xml, рекомендую сделать их копии.

P.P.S. А на этой неделе заметок больше нет — еду на День независимости Украины на Родину — в Запорожье. Всех с праздником и «Ще не вмерла!!!».

Создайте бесплатный сайт или блог на WordPress.com.