Подключение к старым серверам MySQL

Я понимаю, что функции PHP mysql_* устарели и Я не должен их использовать.

Однако у нас есть несколько устаревших баз данных MySQL 4.0, которые ни mysqli_*, ни PDO поддерживают функции. Каков наилучший способ продолжить использование последних версий PHP и все еще иметь возможность подключаться к этим базам данных?

(Основываясь на описании в верхней части начальной страницы PDO, я изначально думал, что PDO может быть вариантом, но Changelog далее по странице предполагает, что поддержка pre-4.1 была удалена в PHP 5.4)

Я понимаю, что MySQL 4.0 составляет 10 лет, и настоящая проблема здесь что мы все еще используем его. Модернизация MySQL - это отдельная проблема, которая вне сферы моего влияния и этого вопроса. Что я делаю есть контроль над версией PHP, которую мы используем, - и я буду ненавидеть должны перестать обновлять PHP только потому, что нам нужно подключиться к некоторым старым базы данных.

Обновлено (2):

Я обновил этот вопрос, чтобы отразить мое новое понимание того, что даже PDO больше не будет подключаться к этим старым серверам MySQL.

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

По этой причине инвазивные решения, такие как переписывание кода или обновление версии MySQL, вряд ли будут стоить. Если они являются единственными доступными решениями, мы, скорее всего, ничего не сделаем - используя mysql_* как можно дольше, а затем замораживая версию PHP (по крайней мере для этих приложений), как только последний PHP больше не сможет подключиться.

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

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

Ответы

Ответ 1

Вы можете использовать либо функции mysql_ *, либо PDO для подключения с PHP 5.4 до MySQL 4.0. Я только что построил MySQL 4.0.30 и запустил его с помощью Sandbox. Затем я успешно проверил пример кода ниже.

Однако вы не можете использовать протокол TCP/IP.

Вы можете обращаться к MySQL только локально, используя сокет unix. Используйте имя хоста "localhost" и убедитесь, что ваш php.ini правильно настроил mysql.default_socket для вашего экземпляра MySQL.

Чтобы использовать метод локального доступа, ваше приложение PHP и сервер базы данных должны быть установлены на одном компьютере.

<?php

print "PHP VERSION = " . phpversion() . "\n";

print "\nTEST DEPRECATED EXT/MYSQL:\n";
mysql_connect('localhost', 'msandbox', 'msandbox');
$result = mysql_query("SELECT VERSION() AS 'MySQL VERSION'");
while ($row = mysql_fetch_assoc($result)) {
  print_r($row);
}

print "\nTEST PDO_MYSQL:\n";
try {
  $dbh = new PDO('mysql:host=localhost', 'msandbox', 'msandbox');
  $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch(PDOException $err) {
  die($err->getMessage());
}

$stmt = $dbh->prepare("SELECT VERSION() AS 'MySQL VERSION'");
$result = $stmt->execute();
foreach ($stmt->fetchAll() as $row) {
  print_r($row);
}

Здесь вывод выше script в моей системе:

PHP VERSION = 5.4.15

TEST DEPRECATED EXT/MYSQL:
Array
(
    [MySQL VERSION] => 4.0.30
)

TEST PDO_MYSQL:
Array
(
    [MySQL VERSION] => 4.0.30
)

Ответ 2

Почему бы не обновить mysql? Если вы хотите минимальное изменение, то для выполнения mysqli достаточно выполнить обновление до 4.1. Я думаю, что это первое, что вы должны попробовать, потому что у вас может быть тестовая среда, чтобы увидеть, работают ли старые приложения с 4.1. У вас также есть список изменений 4.1, которые вам нужно проверить, они находятся в http://dev.mysql.com/doc/refman/4.1/en/upgrading-from-previous-series.html

Если тестирование 4.1 выявит некоторые проблемы, вы узнаете, что потребуется более радикальное изменение, и вам нужна эта информация для построения стратегии. Я знаю, что вы хотите постоянно обновлять PHP, просто не оставляйте mysql и ОС позади. У меня была бы стабильная комбинация mysql, os и php для запуска в производстве. Когда придет время для перехода, создайте новую новую среду.

Ответ 3

От mysql_ * до PDO на самом деле не так уж плохо, PDO просто кажется немного пугающим вначале и согласен, несколько сложнее, по крайней мере, для извлечения данных из запросов (IMO).

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

Например,

$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');

и

mysql_query($sql)

стать

$link = new PDO("mysql:host=localhost;dbname=$dbname", $dbuser, $dbpass);

и

$statement = $link->prepare($sql);
$statement->execute(values);

Ответ 4

Это может быть довольно простое решение... Поскольку вы используете устаревшие приложения в устаревшей версии базы данных MySQL. Почему бы вам не сохранить постоянство? Я предполагаю, что приложения размещаются на сервере, который поддерживается самостоятельно, а не сторонним (веб-хостинга).

То, что я предлагаю сделать, это иметь другую машину. Возможно, виртуальный сервер, на котором запущен mysql4.0, и версия PHP, которая подходит для приложений. Затем перенесите все наследие на новый сервер. Тогда вы не будете должны беспокоиться об удалении/амортизации функций mysql_*.

С вашим основным сервером продолжайте обновление, как вы хотите сохранить ваши текущие требования к разработке?

Ответ 5

Унаследованные функции mysql_ * были удалены в версии 5.5.0, выпущенной сегодня (6/20/2013). Я понимаю, что ваши руки связаны с этой старой базой данных, но имейте в виду, что то, что вы сейчас испытываете, известно как технический долг, и это важная концепция, чтобы понять и объяснить ответственным людям.

Я уверен, что вы уже знаете опасности старого программного обеспечения (эксплойты и т.д.), но, очевидно, это относится и к вашему PHP. В настоящее время 5.4.x по-прежнему поддерживается, но, как правило, поддерживаются только две самые последние версии PHP, поэтому средства 5.3.x заканчиваются в ближайшее время и поддерживаются только 5.5.x и 5.4.x. Из-за вашей потребности в устаревшем MySQL вы уже используете самый старый поддерживаемый PHP и играете в опасную игру.

Если бы вы надеялись на какую-то серебряную пулю, я не могу сказать ее проще: нет никого. Вы должны сделать жесткий выбор, поддержать наследие и открыть себя до возможных эксплойтов или нарисовать линию на песке и просто сказать "нет". Я бы хотел сказать, что за все свои годы ИТ я никогда не слышал, чтобы кто-нибудь говорил (особенно с деловыми аспектами) о том, как они были довольны старым наследием.

Ответ 6

Этот ответ был написан, в то время как OP полагал, что PDO может подключаться к MySQL 4.

Что вы можете сделать, так это переписать функции mysql с помощью драйвера PDO, поэтому вы не изменяете исходный код. Если я возьму примеры, данные Серднад, вы можете сделать что-то вроде:

function mysql_connect($dbhost, $dbusr, $dbpass){
  return new PDO("mysql:host=$dbhost;dbname=mydb", $dbuser, $dbpass);
}

function mysql_select_db($db, $link=false){
  // If you were not using the link argument you might use some global instead
  $link->query("USE $db");
  return 1;
}

function mysql_query($sql, $link=false){
  // If you were not using the link argument you might use some global instead
  $statement = $link->prepare($sql);
  return $statement->execute(values);
}

Ну, существует немало функций mysql_ *, но в конце вы можете узнать, какие из них вы действительно используете (а это может быть только несколько) с простым поиском регулярных выражений в вашем источнике.

Думаю, вам нужно быть умным с некоторыми функциями, такими как mysql_escape_string, mysql_affected_rows или mysql_insert_id, но я уверен, что это выполнимо.

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