Php PDO和加载数据本地填充不工作

Php PDO和加载数据本地填充不工作,php,mysql,pdo,Php,Mysql,Pdo,我只是尝试使用加载数据LOCL INFILE和pdo。不适合我。这是我的职责 function connect($db_name,$db_host,$db_user,$db_pass) { try { $this->connect = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass); $this->connect->exec("LOAD

我只是尝试使用加载数据LOCL INFILE和pdo。不适合我。这是我的职责

function connect($db_name,$db_host,$db_user,$db_pass)
{
    try
    {
        $this->connect = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);    
        $this->connect->exec("LOAD DATA LOCAL INFILE 'http://localhost/testoo.csv'
                                INTO TABLE 'parsed'
                                FIELDS TERMINATED BY ','
                                OPTIONALLY ENCLOSED BY '\"'
                                LINES TERMINATED BY '\n'
                                ('name','link','price','brand','imageurl')");

    }
    catch(PDOException $e) 
    {  
        echo $e->getMessage(); 
    }
}
现在什么也没发生。同样的查询也适用于普通的mysql\u查询。对这个问题有什么建议吗

2019年编辑 7年后,桑米奇在这里说,我最初的答案是粗俗的。我甚至搞不懂我到底在说什么“
fgetcsv()
资源使用问题”。7年前的PHP可能缺少今天的一些IO流优化,但我愿意承认这是与PHP无关的资源约束

Jay Dhameliya下面的答案很可能就是您想要的方式。
加载数据填充
应该尽可能快地将数据直接写入mySQL

为了完整性起见,假设存在阻止使用
LOAD DATA infle
[如最近发现的巨大安全漏洞]的因素,并且您希望有效地从文件加载数据,那么您可能希望利用事务来批处理IO和索引写入。例如:

$fname = 'myfile.csv';

if( ! $fh = fopen($myfile, 'r') ) {
    throw new Exception("Could not open $fname for reading.");
}

$dbh = new PDO(...);
$dbh->beginTransaction();
$stmt = $dbh->prepare('INSERT INTO table VALUES (?,?,?,...)')
try {
    while( $params = fgetcsv($fh) ) {
        $stmt->execute($params);
    }
} catch( \PDOException $e ) {
    $dbh->rollBack();
    throw $e;
}
$dbh->commit();
将所有内容批处理到单个事务中仍然是使用
加载数据填充
速度如此之快的部分原因,并且可能是@Benjamin建议使用扩展插入的一个重要部分

原始总答案
  • 确保mySQL和www用户都可以访问相关文件
  • 或者:以编程方式使用和创建插入

    编辑: 为了避免
    fgetcsv()
    [因为它试图一次读取整个文件]的资源使用问题,您可以创建一个类似于下面的循环来读取/插入可管理的块

    <?php
    $fname = 'myfile.csv';
    $chunksize = 50;
    
    if( ! $fh = fopen($myfile, 'r') ) {
        throw new Exception("Could not open $fname for reading.");
    }
    
    $i=0;
    $buffer = array()
    while(!feof($fh)) {
        $buffer[] = fgets($fh);
        $i++;
        if( ($i % $chunksize) == 0 ) {
            commit_buffer($buffer);
            //run inserts
            $buffer = array(); //blank out the buffer.
        }
    }
    
    //clean out remaining buffer entries.
    if( count($buffer) ) { commit_buffer($buffer); }
    
    function commit_buffer($buffer) {
        foreach( $buffer as $line ) {
            $fields = explode(',', $line);
            //create inserts
        }
        //run inserts
        $buffer = array(); //blank out the buffer.
    }
    

    在PDO连接选项中设置属性
    PDO::MYSQL\u ATTR\u LOCAL\u infle

    function connect($db_name,$db_host,$db_user,$db_pass)
        {
            try
            {
                $this->connect = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass,array(PDO::MYSQL_ATTR_LOCAL_INFILE => true));    
                $this->connect->exec("LOAD DATA LOCAL INFILE 'http://localhost/testoo.csv'
                                        INTO TABLE 'parsed'
                                        FIELDS TERMINATED BY ','
                                        OPTIONALLY ENCLOSED BY '\"'
                                        LINES TERMINATED BY '\n'
                                        ('name','link','price','brand','imageurl')");
    
            }
            catch(PDOException $e) 
            {  
                echo $e->getMessage(); 
            }
        }
    

    我也有同样的问题。我的MySQL服务器有正确的本地infle配置,
    PHP/PDO
    也有正确的
    PDO::MySQL\u ATTR\u local\u infle
    conf。 解决方案是(重新)安装php5 mysqlnd。

    $> apt-get update
    $> apt-get install php5-mysqlnd
    

    …成功了:)

    您收到错误消息了吗?您是否打开了错误报告功能?谢谢您,现在已捕获错误!“PDO::exec()[PDO.exec]:加载数据本地填充禁止”web服务器中的文件不是我定义的本地文件。。。它真的适用于旧版扩展吗?
    如果这是一次性的,那么就用php。。。只需从CLI客户端运行查询。。。完成和完成。:-)已经试过1次了。我的问题是,我有像80mb或更多的大文件,所以fgetcsv()是一种缓慢的方式,因为它将首先尝试将所有80mb加载到RAM中。Double或者用于加载X行,创建/运行插入,重复直到EOF。这仍然是一种减慢速度的方法。我必须定期导入3.000.000+行的CSV。我第一次尝试foreach循环和
    fgets()
    需要一整晚的时间,而
    LOAD DATA LOCAL
    可以在几分钟内完成任务。@GielBerkers“仍将”和“将”==您的推测。我想知道,如果不是完全相同的事情,mySQL客户机库会对文件做什么。此外,问题是关于加载数据根本不起作用的事实。@Sammitch如果您对此进行基准测试,您可能会对结果感到惊讶,这就是我在上面的链接中所做的!扩展插入总是要快得多。我确实在每种情况下都使用了事务和非模拟的预处理语句!这是唯一对我们有效的解决方案。感谢您的最佳回答,因为重点是使用实际的PDO。我的猜测是,大多数用户在设置时都会遇到问题,因为他们忘记了允许自动递增字段。。。在Jays的正确示例中,如果有一个自动递增字段(很可能),让我们假设call Table_ID,那么您应该在字段entries之后添加“SET Table_ID=NULL”;我还建议结合上述内容阅读此答案,以帮助理解必要的设置:非常感谢:)这确实是最好的解决方案。解决了我的问题。