Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/253.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP、ORM、MSSQL和Unicode,有可能使它们一起工作吗?_Php_Sql Server_Pdo_Unicode_Orm - Fatal编程技术网

PHP、ORM、MSSQL和Unicode,有可能使它们一起工作吗?

PHP、ORM、MSSQL和Unicode,有可能使它们一起工作吗?,php,sql-server,pdo,unicode,orm,Php,Sql Server,Pdo,Unicode,Orm,如果要将unicode数据保存到MSSQL,则需要将其保存到列类型nvarchar(等)中,并且必须在SQL字符串文本前面加上大写字母N。如果要使用预处理语句,则不需要在值前面加上大写字母N 插入tbl(列)值(N'hello') 如果您使用的是像ZF DB这样的ORM,那么您使用的是PDO连接到MSSQL(或者您正在Windows上部署,在这种情况下,您使用的是SQLSRV或PDO_SQLSRV,一切都将正常工作,我的问题不再有意义) 如果您在Linux上使用任何连接到mssql(sybase

如果要将unicode数据保存到MSSQL,则需要将其保存到列类型nvarchar(等)中,并且必须在SQL字符串文本前面加上大写字母N。如果要使用预处理语句,则不需要在值前面加上大写字母N

插入tbl(列)值(N'hello')

如果您使用的是像ZF DB这样的ORM,那么您使用的是PDO连接到MSSQL(或者您正在Windows上部署,在这种情况下,您使用的是SQLSRV或PDO_SQLSRV,一切都将正常工作,我的问题不再有意义)

如果您在Linux上使用任何连接到mssql(sybase、dblib等)的PDO变体,那么您不会得到真正准备好的语句,只能进行模拟

如果您模拟了准备好的语句,那么在连接级别上,SQL完全是用字符串文字编写的,这意味着您必须在任何潜在的unicode值前面加上N

  • 是否可以使用ZF自动在任何字符值前面加上N
  • 是否有允许这种值操作的ORMs/TableGateway LIB
  • 有没有办法从Linux启用服务器端准备的语句
  • 是否有人真的从Linux代码运行生产PHP,并让它在MSSQL上运行?(如果是,您如何处理Unicode?)
  • 编辑:
    我可以让unicode从Linux保存到MSSQL,但将FreeTDS协议升级到7/8似乎会破坏所有框架/库/orms,因为绝对需要用N前缀改变普通SQL。我不知道互联网上有谁声称升级到协议版本7/8解决了他们的unicode问题,除了以不可移植的方式手工编写每个SQL语句外,他们实际上还做了什么。似乎使用Freetds 4.2是处理Unicode/UTF-8和mssql的最佳方式。

    更新:驱动程序不再处于预览状态。MS已为现在发布的版本提供了官方说明:

    由于MS已下载预览驱动程序,下面的说明现已过时


    嗯,有一个由微软提供的ODBC驱动程序。这应该在这方面提供适当的行为有关我是如何测试其行为的(初步方式),请参见本文末尾。它是针对Azure SQL数据库V12进行测试的

    如何在Ubuntu 16.04上安装Microsoft SQL ODBC驱动程序

    这是在新的Ubuntu 16.04 Azure实例上测试的,该实例基于Canonical提供的Ubuntu 16.04 Azure映像。登录后,我使用
    sudo-I
    切换到root用户,然后:

    apt-get update
    apt-get -y install atool make build-essential libc6 libkrb5-3 libgss3 e2fsprogs openssl equivs
    wget https://download.microsoft.com/download/2/E/5/2E58F097-805C-4AB8-9FC6-71288AB4409D/msodbcsql-13.0.0.0.tar.gz
    atool -x msodbcsql-13.0.0.0.tar.gz
    rm msodbcsql-13.0.0.0.tar.gz
    
    pushd msodbcsql-13.0.0.0/
    ./build_dm.sh --accept-warning | tee build_dm_result.txt
    command=$(cat build_dm_result.txt | grep "Run the command" | cut -d"'" -f2)
    rm build_dm_result.txt
    sh -c "$command"
    popd
    
    echo "/usr/lib64" > /etc/ld.so.conf.d/microsoft-lib64.conf
    ldconfig
    
    pushd msodbcsql-13.0.0.0/
    ./install.sh  install --accept-license
    
    测试它

    用您自己的凭据替换以下命令中的服务器和凭据

    sqlcmd -S somedatabase.database.windows.net -U someuser -P somepassword
    
    <?php
    
    $pdo = new PDO('odbc:Driver={ODBC Driver 13 for SQL Server};Server=tcp:somedatabase.database.windows.net,1433;Database=somedatabase;Uid=someuser@somedatabase;Pwd=somepassword;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;');
    
    $str = 'Árvíztűrő tükörfúrógép, and... 你好,世界';
    
    $pdo->prepare("DROP TABLE test")->execute();
    $pdo->prepare("CREATE TABLE test(a NVARCHAR(MAX))")->execute();
    $stmt = $pdo->prepare("INSERT INTO test VALUES(?)");
    $stmt->bindParam(1, $str);
    $stmt->execute();
    
    $stmt = $pdo->prepare("SELECT * FROM test");
    $stmt->execute();
    $data = $stmt->fetchall();
    var_dump($data[0][0]==$str); //Returns true
    
    $stmt = $pdo->prepare("SELECT * FROM test WHERE a=?");
    $stmt->bindParam(1, $str);
    $stmt->execute();
    $data = $stmt->fetchall();
    var_dump($data[0][0]==$str); //Returns true
    
    此时您应该能够发出SQL命令。好的,让我们用php来实现它

    与php一起使用它

    我们必须确保没有安装libodbc1包,也不会安装它,因为php使用libodbc1包,而不是定制的libodbc1包,这将导致编码问题

    cat > libodbc1<<EOL
    Section: misc
    Priority: optional
    Standards-Version: 3.9.2
    
    Package: libodbc1
    Version: 9999
    Description: fake pkg, so that we satisfy the dependency of php7-odbc, so that we can keep our custom built libodbc
    EOL
    
    equivs-build libodbc1
    dpkg -i libodbc1_9999_all.deb
    rm libodbc1
    rm libodbc1_9999_all.deb
    
    apt-get install php7.0-odbc php7.0-cli
    

    cat>libodbc1Bummer,PDO::lastInsertId不起作用,因此这可能是大多数ORM都无法做到的。我设法修改了ORM,使其不尝试使用PDO::lastInsertId,而是在insert语句中使用OUTPUT子句来获取id。这是一个非常简单的更改。现在一切看起来都很好。你好@Tarnay,很高兴听到这个消息!你修改了什么?我在微软从事驱动程序方面的工作,希望了解更多关于您的问题以及您如何解决它的信息。您好@meet bhagdev!我修改了idiorm,如下所述: