【问题标题】:PHP loop the INSERT MySQL for each resultPHP为每个结果循环INSERT MySQL
【发布时间】:2017-10-30 08:38:14
【问题描述】:

我已经有一个脚本,用简单的 HTML dom 废弃一个 csv 的所有 url。

输出是这样的:

CoolerMaster Devastator II Azul

Coolbox DeepTeam - Combo teclado, ratón y alfombrilla

Asus Claymore RED - Teclado gaming

INSERT INTO productos (nombre) VALUES('Asus Claymore RED - Teclado gaming')

Items added to the database!

INSERT INTO productos (nombre) VALUES('Asus Claymore RED - Teclado gaming')

Items added to the database!

INSERT INTO productos (nombre) VALUES('Asus Claymore RED - Teclado gaming')

Items added to the database!

如您所见,废料是 3 个不同的产品,但是当我尝试插入 MySQL 数据库时,它只保存最后一个产品,但保存了 3 次。

在这里你可以看到我的 PHP 代码:

    <?php

    require 'libs/simple_html_dom/simple_html_dom.php';
set_time_limit(0);


    function scrapUrl($url) 
    {

        $html = new simple_html_dom();


        $html->load_file($url);

        global $name;

        $names = $html->find('h1');

        foreach ($names as $name) {
           echo $name->innertext;
           echo '<br>';


    }

    $rutaCSV = 'csv/urls1.csv'; // Ruta del csv.

    $csv = array_map('str_getcsv', file($rutaCSV));

    foreach ($csv as $linea) {

        $url = $linea[0];
        scrapUrl($url);

    }


$servername = "localhost";
$username = "";
$password = "";
$dbname = "";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 


foreach ($csv as $linea) {

$url = $linea[0];


 $sql = "INSERT INTO productos (nombre) VALUES('$name->plaintext')";
 print ("<p> $sql </p>");    
 if ($conn->query($sql) === TRUE) {
    echo "Items added to the database!";
 } else {
    echo "Error: " . $sql . "<br>" . $conn->error;
 }
}

$conn->close();



?>

所以,我需要的是 MySQL 查询添加:

INSERT INTO productos (nombre) VALUES('CoolerMaster Devastator II Azul')

Items added to the database!

INSERT INTO productos (nombre) VALUES('Coolbox DeepTeam - Combo teclado, ratón y alfombrilla')

Items added to the database!

INSERT INTO productos (nombre) VALUES('Asus Claymore RED - Teclado gaming')

Items added to the database!

非常感谢任何帮助!

谢谢你和最好的问候

【问题讨论】:

  • 为什么不使用单个INSERT 语句?
  • 你好@TimBiegeleisen,对不起,我不明白你的意思......你能再解释一下吗?谢谢!
  • 为什么在你的 INSERT 语句中使用 "$name->plaintext",而这个变量 "$name" 甚至没有在你的循环中设置?
  • @MihanEntalpo 因为我不想添加到我的 MySQL 表中的是产品的所有名称。 (每一个MySQL表行)
  • 你为什么在 csv 上循环 2x,为什么不合并它。

标签: php mysql loops foreach


【解决方案1】:

你的代码有很多问题。

  1. 首先,您有函数 scrapUrl,它以 $url 作为参数,但不输出任何内容。它正在设置全局 $name 变量,但是,虽然它找到了几个名称,但它只将最后一个放入 $name 变量,因为它正在遍历一系列 $name,将它的文本放入 $name,然后去下一个,因此,只有最后一项存储到您的 $name 变量中。

我建议您更改您的 scrapUrl 函数,以便将报废产品的名称存储到一个数组中,然后返回该数组。

  1. 其次,我无法理解您如何将数据放入 csv 文件中,您提供的代码看起来应该无法正常工作。您确定在 csv 文件中写入正确的数据吗?也许在这里您只是从文件中读取数据 - 在这种情况下,我很抱歉。

  2. 第三个:你正在从csv读取数据,并且在循环中逐行移动时,但数据无处可去。在我看来,你应该把 $linea[0] 放到你的 SQL 查询中,但是你把 $name->plaintext 放在哪里,当 $name 在你的 scrapUrl 中只设置一次时,正如我上面提到的那样。

我建议您在 SQL 查询中使用正确的变量将数据传递给它。

另外,最好使用 PDO 和准备好的语句,而不是在字符串文字 SQL 查询中插入原始数据。

【讨论】:

  • 您好,感谢您的回复。 1-是的,我认为这就是问题所在。如何将报废产品的名称存储到一个数组中,并在我的 MySQL 查询中返回该数组? 2-我不需要在 csv 上写任何东西,csv 仅用于读取 URL 以抓取 3- $linea[0] 只是我的 csv 文件上的每一行,对吗? (所以,它是 URL,我的 MySQL 表中不需要它们。)我只需要 mysql 表中的正确名称。提前致谢
  • 1.在您的 foreach ($names as $name) 循环中,编写类似 result_array[] = $name->plain_text 的内容。因此,在函数结束时,您将获得填充的 result_array,您可以返回到外部范围。 2 和 3。好吧,我不过,您将收集的名称保存到 csv 中。因此,由于您不需要将名称保存到 csv 中,您应该在最后一个循环中为您的 linea[0] 运行 scrapUrl,并遍历返回的名称(scrapUrl 应该返回它,记得吗?),使用 INSERT 查询插入它们。试试看。
  • 当我将 result_array[] = $name->plain_text 添加到我的 foreach $names as $name 时,我遇到了这个错误:致命错误:无法使用 [] 进行阅读
  • 你没有忘记在 result_array 之前的 $ 符号吗?
【解决方案2】:

这是您的代码,刚刚格式化:(请检查您是否缺少}

function scrapUrl($url) 
{
    $html = new simple_html_dom();
    $html->load_file($url);
    global $name;  // -- using global is crap - I would avoid that.  Pass the object in as an argument of the function eg.  scrapUrl($url, $name) 
    $names = $html->find('h1');
    foreach ($names as $name) {
         // -- your re-assigning $name overwriting you global on each iteration of this loop 
        // -- What is the purpose of this? it does nothing but output?
        echo $name->innertext;
        echo '<br>';
    }
// -- missing }  where is this function closed at?

    $rutaCSV = 'csv/urls1.csv'; // Ruta del csv.
    $csv = array_map('str_getcsv', file($rutaCSV));

    foreach ($csv as $linea) {
        // -- this can be combined with the one with the query
        // -- just put the function call in that one and delete this one
        $url = $linea[0];
        scrapUrl($url); //recursive? depends where you function is closed
        // -- whats the purpose of this function, it returns nothing?
    }

    $servername = "localhost";
    $username = "";
    $password = "";
    $dbname = "";

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    } 

    foreach ($csv as $linea) {
        $url = $linea[0]; // -- whats this url used for?
        $sql = "INSERT INTO productos (nombre) VALUES('$name->plaintext')";
         // -- query is vulnerable to SQL injection? prepared statement
         // -- whats $name->plaintext? where is it assigned at?
        print ("<p> $sql </p>");    
        if ($conn->query($sql) === TRUE) {
            echo "Items added to the database!";
        } else {
            echo "Error: " . $sql . "<br>" . $conn->error;
        }
       // -- when you loop over the CSV but insert $name->plaintext multiple times
       // -- where is that property changed inside this loop, how is it correlated to the csv data
    }

    $conn->close();

所以首先你错过了一个结束 } 取决于应该在哪里,取决于你还有什么错。

你们中的一个 CSV 循环可以被消除(也许),反正我用 cmets 把一堆笔记像这样// --

您的主要问题,或者您插入的原因相同是这些行

foreach ($csv as $linea) {
    $url = $linea[0]; // -- whats this url used for?
    $sql = "INSERT INTO productos (nombre) VALUES('$name->plaintext')";
    // -- $name->plaintext does not change per iteration of the loop
    // -- you are just repeatedly inserting that data
   ...

看到你插入了$name-&gt;plaintext 的值,但这与$csv 变量没有关联,你也没有修改它。它保持不变也就不足为奇了。

好的,现在我已经分解了您的代码(没有任何个人信息)。让我们看看我们是否可以简化一下。

更新 鉴于上述代码,这是我能做的最好的事情。我只是把它组合起来,修正了一些逻辑错误,把它删减并简化了。使任务过于复杂是初学者的常见错误。 (但我没有办法测试这个)

<?php
$servername = "localhost";
$username = "";
$password = "";
$dbname = "";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 

$rutaCSV = 'csv/urls1.csv'; // Ruta del csv.
$csv = array_map('str_getcsv', file($rutaCSV));

//prepare query outside of the loops
$stmt = $conn->prepare("INSERT INTO productos (nombre)VALUES(?)");

foreach ($csv as $linea) {

    //iterate over each csv line
    $html = new simple_html_dom();

    //load url $linea[0]
    $html->load_file($linea[0]); 

    //find names in the document, and return them
    foreach( $html->find('h1') as $name ){
        //iterate over each name and bind elements text to the query
        $stmt->bind_param('s', $name->plaintext);

        if ($stmt->execute()){
            echo "Items added to the database!";
        } else {
            echo "Error: " . $sql . "<br>" . $conn->error;
        }
    }
}

在那里我进一步简化了它,因为拥有函数scrapUrl() 并没有什么意义。我们没有重复使用该代码,因此它添加了一个函数调用并通过拥有它使代码更难阅读。

即使它无法正常工作,我也鼓励您将原始代码与我拥有的代码进行比较。并在你的脑海中逐步完成它,这样你就可以了解我是如何删除一些冗余等的。

供参考

希望对您有所帮助,干杯!

【讨论】:

  • 我在 MySQL 中有相同的输出和相同的 INSERT。只有最后一个报废的产品名称被添加到我的 MySQL 表中。 :( echo $name->innertext 的目的;它只是为了查看输出并知道我在哪里。
  • @A.Sanchez - 这是因为当您将 $name-&gt;plaintext 插入数据库时​​,您永远不会在最后一个循环中更改它。
  • 哇...是的...我很抱歉我是 PHP 新手,这是我的第一个项目。我真的不知道该怎么做 :( 无论如何感谢您的帮助
  • @A.Sanchez - 查看我的更新。我没有办法对此进行测试,因为我没有 CSV 或 DB 模式。即使我确实有这些,我今天早上可能也懒得去做了。
  • 谢谢@ArtisticPhoenix,我会试试你的例子。我会努力做到的。我回头告诉你!最好的问候
【解决方案3】:

好吧,在考虑了很长时间之后,我设法让它发挥了作用。

我留下代码以防其他人使用。

    <?php


    require 'libs/simple_html_dom/simple_html_dom.php';
set_time_limit(0);


    function scrapUrl($url) 
    {

        $html = new simple_html_dom();

        $html->load_file($url);

        global $name;
        global $price;
        global $manufacturer;


        $result = array();
        foreach($html->find('h1') as $name){
        $result[] = $name->plaintext;
            echo $name->plaintext;
            echo '<br>';
        }
        foreach($html->find('h2') as $manufacturer){
        $result[] = $manufacturer->plaintext;
            echo $manufacturer->plaintext;
            echo '<br>';
        }
        foreach($html->find('.our_price_display') as $price){
        $result[] = $price->plaintext;
            echo $price->plaintext;
            echo '<br>';
        }

        $servername = "localhost";
$username = "";
$password = "";
$dbname = "";

        // Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 

        $price_go=str_replace(",",".",str_replace(" €","",$price->plaintext));


$sql = "INSERT INTO productos (nombre, nombreFabricante, precio) VALUES('$name->plaintext', '$manufacturer->plaintext', $price_go)";


print ("<p> $sql </p>");

if ($conn->query($sql) === TRUE) {
    echo "Producto añadido al comparador!";
    echo '<br>';
} else {
    echo "Error: " . $sql . "<br>" . $conn->error;
}

$conn->close();
        //echo $url;

    }

    $rutaCSV = 'csv/urls1.csv'; // Ruta del csv.

    $csv = array_map('str_getcsv', file($rutaCSV));

    //print_r($csv); // Verás que es un array donde cada elemento es array con una de las url.





foreach ($csv as $linea) {
    $url = $linea[0];
    scrapUrl($url);
}


    ?>

我很确定我的代码中有一些垃圾,但它确实有效。

我希望它对某人有所帮助。

向所有的帮助表示问候和感谢。

【讨论】:

    猜你喜欢
    • 2015-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    相关资源
    最近更新 更多