Search code examples
phpmysqlpdoprepared-statementbindparam

Problems to insert data in mysql with PDO


I am making a Crawler with php, and this Crawler is working

<?php 

  $dbHost = 'localhost';
  $dbName = 'invento';
  $dbUser = 'root';
  $dbPass = '';

try {

  $pdo = new PDO("mysql:host=$dbHost;dbname=$dbName","$dbUser", "$dbPass");
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

} catch(Exception $e) {

  echo $e->getMessage();
}


$html = file_get_contents('https://www.google.com');
preg_match('/<title>(.*)<\/title>/i', $html, $title);

$title_out = $title[1];

$sql = "INSERT INTO prueba (title) VALUES ($title_out)";

  $query = $pdo->prepare($sql);

  $result = $query->execute([
    'title' => $title_out
  ]);

but I have some problems to add the title to database, this is the error:

Fatal error: Uncaught PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Google' in 'field list' in C:\xampp\htdocs\webcrawler\php-web-crawler\index.php:29 Stack trace: #0 C:\xampp\htdocs\webcrawler\php-web-crawler\index.php(29): PDOStatement->execute(Array) #1 {main} thrown in C:\xampp\htdocs\webcrawler\php-web-crawler\index.php on line 29


Solution

  • You are misusing prepared statements. To be effective you need to use a placeholder in place of the value.

    $title_out = $title[1];
    $sql = "INSERT INTO prueba (title) VALUES (:title)";
    $query = $pdo->prepare($sql);
    $result = $query->execute(['title' => $title_out]);
    

    You also need to match the placeholder to the key, if you use the named placeholders. I usually use unnamed placeholders:

    $title_out = $title[1];
    $sql = "INSERT INTO prueba (title) VALUES (?)";
    $query = $pdo->prepare($sql);
    $result = $query->execute([$title_out]);
    

    Additionally you shouldn't use a regex on HTML. It can break for many reasons. Using a parser will be more robust:

    $html = file_get_contents('https://www.google.com');
    $dom = new domdocument();
    $dom->loadHTML($html);
    $titleout = $dom->getElementsByTagName('title')[0]->nodeValue;