2014-10-08 68 views
1

在PHP我有一个简单的数组称为$allFiles像:PHP PDO MYSQL - 最简单的方法来比较数组来查询并返回一个数组结果不在查询结果?

Array 
(
    [0] => test1.csv 
    [1] => test2.csv 
    [2] => test3.csv 
) 

在MySQL中我有一个具有类似值的表:

| ID | PROCESSED | 
| 0 | test2.csv | 

什么是最简单的方法(使用PDO作为连接方法)比较$allFiles表,并返回一个包含一个新的数组$newFiles

Array 
(
    [0] => test1.csv 
    [1] => test3.csv 
) 

(这些是在MySQL中没有表示的文件)

我已经通过手册,但似乎无法找到任何与此完全相关的内容,但我可能错过了某些内容。任何输入将不胜感激,谢谢!

+0

http://php.net/manual/en/function.array-diff.php? – Sherlock 2014-10-08 12:54:22

+0

没有现成的功能来做到这一点。大多数情况下,您会发现没有即时解决方案来解决您的问题。您必须自己编写代码,这并不难:查询DB获取所有文件名,使用结果创建一个数组,然后获取您拥有的数组之间的差异,并查询结果 – 2014-10-08 12:58:01

+0

@ Sherlock非常感谢,并没有这么想,因为认为这是一个PDO功能! – 2014-10-08 12:59:26

回答

2

有没有现成的函数来做到这一点。大多数情况下,您会发现没有即时解决方案来解决您的问题。您必须自己编写代码,这并不难:查询获取所有文件名的数据库,使用结果创建数组,然后在您拥有的数组与查询结果之间获取差异。
一个基本的例子是:

$stmt = $pdo->prepare('SELECT PROCESSED FROM db.table WHERE PROCESSED IN (?,?,?)'); 
$stmt->execute($allFiles); 
$existing = array(); 
while($row = $stmt->fetch(PDO::FETCH_OBJ)) 
    $existing[] = $row->PROCESSED;//construct array containing existing values 
$notFound = array_diff($allFiles, $existing); 
var_dump($notFound); 

你可以使查询一点点更有活力,通过使用$allFiles数组的长度,并相应地添加?占位符:

$allFiles = array_filter(array_unique($allFiles));//clean array 
$placeholders = array_fill(0, count($allFiles), '?'); 
$stmt = $pdo->prepare(
    'SELECT PROCESSED FROM db.table WHERE PROCESSED IN ('.implode(',', $placeholders).')' 
); 
//alternative: 
$stmt = $pdo->prepare(
    'SELECT PROCESSED FROM db.table WHERE PROCESSED IN ('. 
    substr(
     str_repeat('?,',count($allFiles)),//repeat ?, as many times as there are values 
     0,-1//remove trailing "," 
    ).')' 
); 
$stmt->execute(array_values($allFiles));//better safe than sorry 
//rest is the same as before 

这让你处理任何长度的数组。

+0

感谢您的详细解答,非常有意义!只是做了一些现在很像你的第一个例子,只看到所有这些答案。令人敬畏的比较。我正在玩弄你的“动态”替代选项。与此有关的两个问题,您在'count($ allFiles))'后面缺少一个逗号?第二,当我运行这个我得到:'致命的错误:未知的异常'PDOException'消息'SQLSTATE [HY093]:无效的参数编号:参数未定义'。这指向执行线。有点困惑,因为我的经验大部分是与Mysqli :) – 2014-10-08 13:34:48

+0

@IndigoIdentity:添加逗号(确实是一个错字),至于致命的错误:'$ allFiles'数组可能是关联的,或有不连续的索引('[0 =>'',2 =>'']'),你可以通过用'$ stmt-> execute(array_values($ allFiles)'替换'$ stmt-> execute($ allFiles) );'也许首先调用'array_filter'和'array_unique',重新分配'$ allFiles'以避免'null'值和重复项更新我的答案中的那一点, – 2014-10-08 14:03:22

+0

嗨,感谢您的更新。随着我想出了什么问题。当我读取包含csv文件的目录的内容时,我删除“。”和“..”。这样做的结果是数组以数字2开头(因为我们已经从数组中取出了2个数值),这就是我所要解决的问题。用'array_values()'重新编排它们就像一个魅力,非常感谢所有的输入,因为我现在觉得更聪明! – 2014-10-08 18:52:28

2

PDO从表中返回一个值的数组。你可以检查你的结果是否已经在db数组中。你可以检查数组键,如果你的结果已经在PDO数组中,可以跳过这个结果。如果您的结果不在PDO数组中,则使用该值或数值构建一个新数组。

注意:PDO为一条记录返回一个数字和文本键。当你检查密钥是否存在时,你必须检查你的密钥是否是一个数字密钥。如果是数字,跳过那一个。

2

就像评论中的家伙所说的,没有PDO功能完全做到这一点。你必须首先收集你的结果,把它们放在一个数组中,并使用array_diff()

粗糙例如:

$allFiles = ['test1.csv', 'test2.csv', 'test3.csv']; 

$con = new PDO('mysql:host=localhost;dbname=DATABASE', 'username', 'password'); 
$query = $con->query('SELECT PROCESSED FROM table_name'); 
$db_results = []; 
while($row = $query->fetch(PDO::FETCH_ASSOC)) { 
    $db_results[] = $row['PROCESSED']; 
} 

$results = array_diff($allFiles, $db_results);