在Linux上通过PHP从MS SQL Server的非模拟准备语句支持

概要

我试图使用预处理语句来停止SQL注入,但无法find我需要的支持,以确保它正常工作。


脚本

我正在Linux上托pipe一个站点,它使用FreeTDS版本0.91连接到Microsoft SQL Server,特别是使用FreeTDS的dblib 。 我已经将数据库连接的tds版本设置为7.4,并使用PHP的PDO对象。

根据FreeTDS文档 ,4.2不支持预准备语句:

TDS 4.2有局限性

  • 当然,只有ASCII码。
  • RPC不受支持。
  • BCP不受支持。
  • varchar字段限制为255个字符。 如果你的表定义了更长的字段,它们将被截断。
  • dynamic查询(也称为准备语句)不受支持。

然而没有任何信息表明7.4不支持准备好的语句,这给了我合理的信心,他们至less不会抛出驱动错误。

PHP的PDO通过PDO::setAttribute()支持特定于连接的属性。 我对PDO::ATTR_ERRMODE感兴趣,将所有错误设置为exception, PDO::ATTR_EMULATE_PREPARES强制数据库在兼容的情况下执行预处理语句。


问题

在testing连接时,我收到以下错误:

数据库错误:SQLSTATE [IM001]:驱动程序不支持此function:驱动程序不支持设置属性

无法设置PDO::ATTR_EMULATE_PREPARES ,我无法保证数据库正在按预期执行预准备语句。

有没有办法修改我的方法,或者有其他方法来保证准备好的语句在Linux上的MS SQL Server上安全地执行?

使用ODBC而不是dblib ,它提供了PDO的全部功能。 请注意,有两种可能的ODBC配置: 独立的ODBC和带有ODBC驱动程序的FreeTDS 。 根据我的经验,为连接设置字符集,必须使用ODBC驱动程序通过FreeTDS完成,从而使组合配置更为可取。


ODBC安装程序

我搜索了许多不同的StackOverflow文章和网上的各种文档资源,以了解如何正确安装ODBC。 我从以下三个引用的混合中拉出我的解决方案:

  • unixODBC安装文档
  • FlipperPA的答案设置 FlipperPA (顺便做的ODBC)
  • Benny Hill对FreeTDS的这个设置问题的回答

以下是我在基于Debian的系统上使用FreeTDS配置ODBC的步骤列表。

TDS 8.0支持准备好的语句。

注意:不支持连接上的SET NAMES aSET CHARSET a ; 字符集需要通过设置FreeTDS属性来使用组合配置进行定义。 使用独立的ODBC驱动程序将字符集默认为ASCII ,这给了奇怪的结果。 看到我的其他职位的例子可能的问题。

安装需要包:

sudo apt-get install freetds-bin freetds-common unixodbc tdsodbc php5-odbc

  • freetds-bin提供FreeTDS,以及tsqlisql (稍后用于调试)。
  • freetds-common已经安装在系统上,但不包含两个调试工具。 定义配置后在以后安装freetds-bin不会造成问题。
  • unixodbc是ODBC驱动程序
  • tdsodbc为ODBC提供了TDS协议
  • php5-odbc是使用ODBC驱动程序的php模块。 请注意,您的PHP版本可能与我的不同。

配置独立的unixODBC

/etc/odbcinst.ini ODBC驱动程序设置:

 [odbc] Description = ODBC driver Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so Setup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so UsageCount = 1 

/etc/odbc.ini创建系统范围的数据源名称配置:

 [datasourcename] Driver = odbc Description = Standalone ODBC server = <IP or hostname> Port = <port> TDS_Version = 8.0 

配置unixODBC和FreeTDS:

/etc/odbcinst.ini ODBC驱动程序设置:

 [odbc] Description = ODBC driver Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so Setup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so UsageCount = 1 

/etc/odbc.ini创建系统范围的数据源名称配置:

 [datasourcename] Driver = FreeTDS_odbc Description = Uses FreeTDS configuration settings defined in /etc/freetds/freetds.conf servername = datasourcename TDS_Version = 8.0 

/etc/freetds/freetds.conf中将ODBC数据源名称配置添加到FreeTDS:

 [datasourcename] host = <IP or hostname> port = <port> client charset = UTF-8 tds version = 8.0 text size = 20971520 encryption = required 

重要提示:确保odbc文件可以被正在读取的进程读取。 如果您使用www-data用户运行Web服务器,则必须具有正确的权限才能读取这些文件!

您现在可以在freetds.conf设置连接字符集,并使用PDO连接到数据库

 $pdo = new PDO('odbc:datasourcename'); 

测试:

使用tsql检查FreeTDS是否已配置并可以连接到数据库。

tsql -S数据源名称-U用户名-P密码

使用isql检查ODBC是否正确连接。

isql -v数据源名称用户名密码

链接ODBC与PHP:

通过添加以下内容将ODBC PHP模块添加到php.ini

扩展= odbc.so

请注意,您的php.ini位置将取决于您正在使用的Web服务器。 使用<?php phpinfo(); ?> <?php phpinfo(); ?>并通过网络服务器查看它的位置。

重新启动Apache

编辑:添加有关驱动程序的字符集功能的信息,因为我遇到了独立的ODBC配置问题,它会忽略任何改变连接字符集的尝试。