I have working code with MySQLi, but I am making some new project and want to do with PDO, that shows multi-level category view. I'm new with PDO and still learning.
This is my working MySQLi:
function categoryTree($parent_id = 0, $sub_mark = ''){
global $db;
$query = $db->query("SELECT * FROM categories WHERE parent_id = $parent_id ORDER BY name ASC");
if($query->num_rows > 0){
while($row = $query->fetch_assoc()){
echo '<tr><td>'.$sub_mark.''.$row['name'].'</td><td><button type="button" name="update" id="'.$row["id"].'" class="btn btn-info btn-sm update"><span class="glyphicon glyphicon-pencil"></span></button></td></tr>';
categoryTree($row['id'], $sub_mark.'---');
}
}
}
Closed variant to PDO what I achieve but now working:
function categoryTree($parent_id = 0, $sub_mark = ''){
$query = "SELECT * FROM ws_categories WHERE parent_id = $parent_id ORDER BY name ASC";
$statement = $connection->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
if($result->num_rows > 0){
while ($row = $statement->fetch()) {
echo '<tr><td>'.$sub_mark.''.$row['name'].'</td><td><button type="button" name="update" id="'.$row["id"].'" class="btn btn-info btn-sm update"><span class="glyphicon glyphicon-pencil"></span></button></td></tr>';
categoryTree($row['id'], $sub_mark.'---');
}
}
}
Error:
Fatal error: Uncaught Error: Call to a member function prepare() on null in
p.s. I have included config.php with pdo db connection that connect properly.
Please help me, I try several ways but no success.
Sorry for my English :)
I think you are trying to iterate over the wrong result set. And I am unsure if the attribute num_rows
is set in a fetchAll.
You can replace the if
and while
part with a single while
/foreach
. If you want to use the fetchAll function you can simply foreach
loop over the result set. However, if you do a big query this can take a lot of memory so it is not always preferred to do so.
For the fetchAll solution you would end up with the following:
$results = $query->fetchAll()
foreach ($results as $result) {
var_dump($result); // Process data here.
}
If you want to use the fetch function which is more memory/resource friendly you can use a while loop like you used in MySQLi:
while ($data = $query->fetch()) {
var_dump($data); // Process data here.
}
edit:
I just noticed you are directly inserting variables into a query, this is bad practice as it allows for sql-injection. If you are using PDO anyway take a look at prepared statements you can replace the variable with a placeholder eg. :parent_id
then on your execute call you pass an array which contains the value of the parent_id and it does some sql injection prevention.
That would look like:
$query = 'select * from ws_categories where parent_id = :parent_id';
$statement = $connection->prepare($query);
$statement->execute(['parent_id' => $parent_id]);
Now this code work, but show only parent categories without subcategories:
function categoryTree($parent_id = 0, $sub_mark = ''){
global $connection;
$query = 'SELECT * FROM ws_categories WHERE parent_id = :parent_id';
$statement = $connection->prepare($query);
$statement->execute(['parent_id' => $parent_id]);
while ($row = $statement->fetch()) {
echo '<tr><td>'.$sub_mark.''.$row['name'].'</td><td><button type="button" name="update" id="'.$row["id"].'" class="btn btn-info btn-sm update"><span class="glyphicon glyphicon-pencil"></span></button></td></tr>';
categoryTree($row['id'], $sub_mark.'---');
}
}