我了解PHP的mysql_*
函数已弃用且 I should not be using them 。
但是,我们有几个遗留的MySQL 4.0数据库,mysqli_*
和PDO
函数都不支持连接。继续使用最新PHP版本并仍能连接到这些数据库的最佳方法是什么?
(基于PDO介绍页面顶部的描述,我最初认为PDO可能是一个选项,但是页面下方的更改日志表明在PHP 5.4中已经删除了对4.1之前的支持)
据我所知,MySQL 4.0已经存在了10年,这是真正的问题 是我们还在使用它。升级MySQL是一个单独的问题 超出我的影响范围和这个问题。我所做的 控制是我们使用的PHP版本 - 我讨厌 必须停止升级PHP只是因为我们需要连接到一些旧的 数据库。
我更新了上述问题,以反映我的新理解,即甚至PDO将不再连接到这些旧的MySQL服务器。
我还应该澄清,我们有几个遗留应用程序访问这些数据库,我们希望尽可能少地更改这些应用程序。他们没有积极开发,并且测试涉及重写大部分代码的更改将很快成为一个相当大的QA项目。
出于这个原因,诸如重写代码或升级MySQL版本等侵入性解决方案极不可能是值得的。如果它们是唯一可用的解决方案,我们可能最终无所事事 - 尽可能长时间使用mysql_*
,然后在最新的PHP无法再冻结PHP版本时(至少对这些应用程序而言)连接。
另一方面,技术上复杂的解决方案(例如从头开始编译)绝对是可能的,并且实际上更倾向于进行大量的代码更改。
我现在正在提供赏金,以期获得新答案,提供更复杂的替代方案。
答案 0 :(得分:11)
你可以使用mysql_ *函数或PDO从PHP 5.4连接到MySQL 4.0。我刚刚构建了MySQL 4.0.30并使用MySQL Sandbox启动了它。然后我成功测试了下面的代码示例。
但是,您无法使用TCP / IP协议。
您只能使用unix套接字在本地访问MySQL。使用主机名'localhost'并确保您的php.ini已为您的MySQL实例正确配置mysql.default_socket
。
要使用本地访问方法,必须在同一主机上安装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);
}
以下是我系统上面脚本的输出:
PHP VERSION = 5.4.15
TEST DEPRECATED EXT/MYSQL:
Array
(
[MySQL VERSION] => 4.0.30
)
TEST PDO_MYSQL:
Array
(
[MySQL VERSION] => 4.0.30
)
答案 1 :(得分:2)
为什么不升级mysql?如果你想要最小的改变,那么升级到4.1就足以让mysqli运行。我认为这是你应该尝试的第一件事,因为你可以有一个测试环境来查看旧的应用程序是否适用于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组合在生产中运行。现在是时候继续前进,建立一个完整的新环境。
答案 2 :(得分:1)
从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);
答案 3 :(得分:1)
这可能是一个非常简单的解决方案...当您在过时的MySQL数据库版本上运行遗留应用程序时..为什么不保持连续性?我假设应用程序托管在由您自己维护而不是第三方(网络托管)的服务器上
我建议做的是拥有一台不同的机器。可能是运行mysql4.0的虚拟服务器和适合应用程序的PHP版本..然后将所有遗留的资源迁移到新服务器..然后你就不会必须担心mysql_*
函数的删除/折旧..
使用主服务器,按照您当前的开发要求继续升级?
答案 4 :(得分:1)
遗留的mysql_ *函数已于今天(2013年6月20日)发布的5.5.0中删除。我意识到你的手与这个旧数据库有关,但请记住你现在所经历的是technical debt,这是一个重要的概念,可以理解并向负责人解释。
我确定你已经知道旧软件(漏洞利用等)的危险,但显然这也适用于你的PHP。目前仍支持5.4.x,但一般来说只支持2个最新版本的PHP,因此5.3.x即将到期,仅支持5.5.x和5.4.x.由于您需要遗留MySQL,您已经使用了最老的受支持的PHP,这是一个危险的游戏。
如果你希望获得一些银弹,我不能说它比任何一个更简单:。你必须做出艰难的选择,支持遗产并让自己打开最终的攻击,或者在沙滩上画一条线,然后说不。我想说,在我多年的IT工作中,我从来没有听到任何人说(特别是在商业方面)他们对保留旧的遗产有多高兴。
答案 5 :(得分:0)
这个答案是在OP认为PDO可以连接到MySQL 4时编写的。
您可能会做的是使用PDO驱动程序重写mysql函数,因此您不需要更改原始代码。如果我采用Serdnad给出的例子,你可以做类似的事情:
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,我认为您可以在不更改原始代码行的情况下实现目标。
答案 6 :(得分:0)
这是一个老问题,但出奇地相关。答案其实很简单。如果您有一个旧的 mysql,您需要通过“新”版本的 PHP 从中提取数据,只需使用新版本的 MariaDB 设置从属。它应该是您迁移过程的一部分。
复制到新版本的 MariaDB,并连接到该从属设备以读取数据(您应该将其设置为只读副本)。