I'm trying to learn PHP and MySQL. I've got a database and some retrieval happening, but when I used fetchObject() I get 2 instances returned. First tried:
class Food {
// Properties
public $id;
public $version;
public $name;
public $solid;
public $servingtext;
public $servingmeasure;
public $servingamount;
private function __construct__() {}
public static function get_with_id ($dbconn,$id, $version) {
$stmt = $dbconn->prepare('SELECT * FROM Foods WHERE Id = :Id and Version = :Version;');
$stmt->execute([':Id' => $id, ':Version' => $version]);
return $stmt->fetchObject(__CLASS__);
// return $answer;
}
// Methods
function set_id($id){
$this->id = $id;
}
etc. with sets and gets
Called with
require "./templates/header.php";
try
{
include __DIR__ . '../../connection.php';
$conobj = new Connection();
$dbconn = $conobj->get_connection();
} catch (Throwable $t) {
error_log(__FILE__ . ':' . $t->getMessage());
echo 'Connection Error ' . $t->getMessage();
}
require "./models/food.php";
$food = Food::get_with_id ($dbconn,2,0);
var_dump($food);
Result:
object(Food)#4 (14) { ["id"]=> NULL ["version"]=> NULL ["name"]=> NULL ["solid"]=> NULL ["servingtext"]=> NULL ["servingmeasure"]=> NULL ["servingamount"]=> NULL ["Id"]=> int(2) ["Version"]=> int(0) ["Name"]=> string(35) "Sanitarium Weet-Bix Blends Hi-Bran+" ["Solid"]=> int(1) ["ServingText"]=> string(28) "1 serving = 40g (2 biscuits)" ["ServingMeasure"]=> string(1) "g" ["ServingAmount"]=> int(40) }
There should be just 7 fields, but the first set are all NULL and then there's the object I'm hoping for.
I tried..
<?php
class Food {
// Properties
public $id;
public $version;
public $name;
public $solid;
public $servingtext;
public $servingmeasure;
public $servingamount;
private function __construct__() {}
// Methods
function set_id($id){
$this->id = $id;
}
with
<?php
require "./templates/header.php";
try
{
include __DIR__ . '../../connection.php';
$conobj = new Connection();
$dbconn = $conobj->get_connection();
} catch (Throwable $t) {
error_log(__FILE__ . ':' . $t->getMessage());
echo 'Connection Error ' . $t->getMessage();
}
require "./models/food2.php";
$id = 2;
$version = 0;
$stmt = $dbconn->prepare('SELECT * FROM Foods WHERE Id = :Id and Version = :Version;');
$stmt->execute([':Id' => $id, ':Version' => $version]);
$food = $stmt->fetchObject('Food');
var_dump($food);
Same result. Then with the same Food class tried:
<?php
require "./templates/header.php";
try
{
include __DIR__ . '../../connection.php';
$conobj = new Connection();
$dbconn = $conobj->get_connection();
} catch (Throwable $t) {
error_log(__FILE__ . ':' . $t->getMessage());
echo 'Connection Error ' . $t->getMessage();
}
require "./models/food2.php";
$id = 2;
$version = 0;
$food = $dbconn->query('SELECT * FROM Foods WHERE Id = ' . $id . ' AND Version = ' . $version . ';')->fetchObject('Food');
var_dump($food);
Again, the result with 2 entries.
Please can someone help with why I'm getting the NULLs version first. I don't want or need it. Happy to be told it's a newbie error! I have had plenty of success retrieving arrays but would like to go down the OO path.
Thanks, Paul
PHP 8.1.30, MySQL 9.1.0 and NGINX 1.27.2 in a Docker container
fetchObject()
generates the class and gives you the first 7 columns of null, as you added them on the class Food
, and they default to NULL
// Your properties, they all get NULL
public $id;
public $version;
public $name;
public $solid;
public $servingtext;
public $servingmeasure;
public $servingamount;
then the fetchObject() injects more variables: the columns of the result query also turns into class properties and makes it seems like its has duplicated, but we can trace it from the results of the vardump().
id
duplicates with Id
version
duplicates with Version
name
duplicates with Name
...
Make the public properties variables match the column names you get on your query. From id
to Id
, servingtext
to ServingText
, etc.
Or find a way to generate the class without using fetchObject()
.