How to return array from recursive function - php

I couldn't find solution for this and I don't have much time for this. So what I want is to make function that I give category ID and it returns all ID's of categories which are it's child categories.
function getID($var) {
$categories = array();
function getChildren($id) {
$result = mysql_query("SELECT * FROM categories WHERE parentID = '$id'");
echo "<ul>";
while ($row = mysql_fetch_array($result)) {
echo "<li><a>{$row['ID']}</a>";
$categories[] = $row['ID'];
getChildren($row['ID']);
echo "</li>";
}
echo "</ul>";
}
getChildren($var);
return $categories;
}
I wan't to store everything in $categories array. $var is category ID which I give to function. When I call this function it prints list of exactly what I want't but array is empty.

It seems you have a scope problem. Try this:
function getChildren(&$categories, $id) {
$result = mysql_query("SELECT * FROM categories WHERE parentID = '$id'");
echo "<ul>";
while ($row = mysql_fetch_array($result)) {
echo "<li><a>{$row['ID']}</a>";
$categories[] = $row['ID'];
getChildren($categories, $row['ID']);
echo "</li>";
}
echo "</ul>";
}
function getID($var) {
$categories = array();
getChildren($categories, $var);
return $categories;
}
Here is the PHP reference page describing how to pass by reference instead of by value. Basically it says that any function parameter which has a & in front of it will be passed by reference instead of by value.

$categories only exists in the scope of get children. You could either pass it by reference as second parameter or create get children as a closure with use (&$categories)

function getChildren($id, $categories)
should work.
The array was out of scope, so the function didn't touch the one you are returning. It created a new local $categories inside the function.

Related

How do I build this array to output?

I have the following function which fetches some data from a MySQL table:
function readQuestion ($quizType, $questionId) {
$data = array();
$query = $this->dbConnection->query("SELECT * FROM $quizType WHERE id = $questionId");
foreach ($query as $row) {
var_dump($row);
};
echo $data
}
How can I push all the returned data into an array, where each member is indexed by a number?
Do I need to use echo or return at the end? They seem to have the same effect.
EDIT: Is this the correct way of returning results of the query? I am passing it to the front-end.
$questionData = $controller->readQuestion($quizType, $questionId);
return $questionData;
In general your function must looks like:
function readQuestion ($quizType, $questionId) {
$data = array();
$query = $this->dbConnection->query("SELECT * FROM $quizType WHERE id = $questionId");
return $query;
}
But, you have to look what is inside $query variable. If it is array - just return this array, if not - maybe it is some iterator, hence you have to check it and try to find method like toArray or something like that... Otherwise, you have to do something like:
$data = [];
foreach ($query as $row) {
$data[] = $row;
};
return $data;
Now you can use this function like:
var_dump(readQuestion($quizType, $questionId));
Take a look up here on how to secure your data.
Anyway, as I said in the comment you cannot use echo on an Array. And you can't do anything with the output of var_dump.
Change var_dump($row); for $data[] = $row;
and change echo $data; for return $data;
function readQuestion ($quizType, $questionId) {
$data = array();
$query = $this->dbConnection->query("SELECT * FROM $quizType WHERE id = $questionId");
foreach ($query as $row) {
$data=$row;
};
return $result;
}

echo result from function from table in database

so i am learning to write functions. Now i know how to echo stuff into a foreach but i do not know how to print a single row outside a foreach (like i only have 1 row in my table and want to print the id and username out of it) how do i do this?
my function :
public function gegevens(){
$stmt = $this->conn->prepare("SELECT * FROM gegevens_locatie");
$stmt->execute();
$result = $stmt->fetchAll();
//Return result
return $result;
}
when i call that function on my other page i call it with :
require_once 'class/class.overig.php';
$overig = new OVERIG();
i have tried stuff like print_r($overig->gevens()) and with a echo but i cant seem to make it work. So how can i do this?
Because you are using ->fetchAll() you will always get an array of rows even if there is only one row returned. You also need to use the correct method name on your call.
So all you need to do is
$arr = $overig->gegevens();
if ( count($arr) == 1 ) {
echo $arr[0]['id'];
echo $arr[0]['username'];
}
if ( count($arr) > 1 ) {
foreach ( $arr as $row) {
echo $row['id'];
echo $row['username'];
}
}
"I have tried stuff like print_r($overig->gevens()) and with a echo but i cant seem to make it work. So how can i do this?"
The Name of the Method you called does NOT match the Name of the Method in your Class. In your Class, You have: gegevens() but in your Call: you specified: gevens(). Unless this is just a normal Typo; you should start your Debugging from there.
In other words; your Call should have been: print_r($overig->gegevens()).
THE CLASS:
<?php
class OVERIG{
public function gegevens(){
$stmt = $this->conn->prepare("SELECT * FROM gegevens_locatie");
$stmt->execute();
$result = $stmt->fetchAll();
//Return result
return $result;
}
}
USING THE CLASS:
<?php
require_once 'class/class.overig.php';
$overig = new OVERIG();
$result = $overig->gegevens();
// TRY DUMPING THE VARIABLE: $result:
var_dump($result);
// TO ECHO OUT SOME VALUES:
if($result){
foreach($result as $key=>$item){
if(is_string($item)){
echo $item;
}
}
}

How to through multidimensional array in Codeigniter?

I'm trying to get my head around grabbing all variable I need in Codeigniter and then passing those values to the view.
I understand the concept, but am getting stuck on iterating through an array and adding on another array to each of its keys.
The $data['items'] array contains data passed from a model via the get_all() function. The query is basically "Select * from items".
Each item has multiple features and pictures. In order to get the appropriate values I need the id of an item. I can grab this from the first array ($data['items']) which I can then pass to a model function.
I keep getting various errors when trying to do this via the code below. I've tried defining the features and pictures arrays before the foreach loop - still get errors.
I'm sure my syntax is just wrong. Any help is welcome.
$data['items'] = $this->amazon->get_all();
foreach ($data['items'] as $data )
$id = $data->id;
$data['features'] = $this->amazon->get_features($id);
$data['pictures'] = $this->amazon->get_pictures($id);
}
Edit
Based on feedback I've updated the code to this (lines 24 - 30 of the code):
$items = $this->amazon->get_all();
for($i=0; $i<count($items);$i++) {
$data = $items[$i];
$id = $data->id;
$items[$i]['features'] = $this->amazon->get_features($id);
$items[$i]['pictures'] = $this->amazon->get_pictures($id);
}
PHP is complaining with this:
PHP Fatal error: Cannot use object of type stdClass as array in /var/www/ci/application/controllers/main.php on line 28
Here are the functions from the amazon model:
function get_all()
{
$query = $this->db->get('items');
return $query->result();
}
function get_pictures($id) {
$query = $this->db->query("SELECT link FROM pictures WHERE item_id='$id' AND type IN('thumb_set')");
$style = "border-style:solid; border-width:1px";
$class = "modal-thumb";
$results = '';
foreach ($query->result() as $row) {
$results .= "<li style='$style' class='$class'><img src='$row->link' alt=''/></li>";
}
return $results;
}
function get_features($id) {
$query = $this->db->query("SELECT content FROM features WHERE item_id='$id' ORDER BY feature_num DESC");
$results = '';
foreach ($query->result() as $row) {
$results .= "<li>";
$results .= $row->content;
$results .= "</li>";
}
return $results;
}
I'm thinking i need to use 'results_array()' instead of 'results()'? Are my results returned as an object instead of an array the way things are now?
As you said, you have syntax error in the foreach statement, you are redefining the $data array.
foreach ($data['items'] as $data )
Try this:
$items = $this->amazon->get_all();
for($i=0; $i<count($items);$i++){
$data = $items[$i];
$id = $data->id;
$items[$i]['features'] = $this->amazon->get_features($id);
$items[$i]['pictures'] = $this->amazon->get_pictures($id);
}

What's wrong with this recursive function?

Here's my recursive function:
function get_descendants($category_id)
{
global $descendants;
$categories = get_ancestors($category_id);
echo "get_ancestors($category_id);<br>";
// print_r($categories);exit;
if (!is_array($categories))
return;
foreach ($categories as $category)
{
$descendants[] = $category['id'];
// Look for other leafs
get_descendants($category['id']);
}
return $descendants;
}
function get_ancestors($parent_id)
{
global $db, $locale;
$result = $db->query("
SELECT ...
AND parent_id = $parent_id
");
$categories = $result->fetch_all(MYSQLI_ASSOC);
if ($result->num_rows > 0)
{
foreach ($categories as $category)
$data[] = $category;
return $data;
}
}
The problem it's making the same call twice. So this is the result of running the code:
get_ancestors(8);
get_ancestors(1);
get_ancestors(2);
get_ancestors(4);
get_ancestors(5);
get_ancestors(3);
get_ancestors(6);
get_ancestors(8);
get_ancestors(1);
get_ancestors(2);
get_ancestors(4);
get_ancestors(5);
get_ancestors(3);
get_ancestors(6);
Where I should only see:
get_ancestors(8);
get_ancestors(1);
get_ancestors(2);
get_ancestors(4);
get_ancestors(5);
get_ancestors(3);
get_ancestors(6);
What's wrong?
Thanks.
The problem is that you don't want $descendants to be global.
You are sharing one variable across all the recursive calls. It really needs to be local for the logic you're using to be correct.
Instead of global $descendants; do $descendants = array();.

Alphabetical lists in CodeIgniter

Wondering how I can do this with CodeIgniter?
Any help is greatly appreciated!
Thanks.
There's no built in function to do this. You'll have to loop through an sql query to do this...
Select * from table order by field asc
foreach ( $result as $thing ) {
if ( $thing['name'][0] != $first_letter) {
echo '<h2>' . $thing['name'][0] . '</h2>';
$first_letter = $thing['name'][0];
}
echo $result['thing'];
}
this is just a rough example...never echo html like that.
//in model
public function alphaDirectory(){
// Query for data
$sql = "SELECT SUBSTRING(column_name,1,1) AS letter, column_name,column_link FROM table ORDER BY column_name";
$query = $this->db->query($sql);
$columnByName="";
foreach ($query->result() as $row)
{
$columnByName[$row->letter][] = array($row->column_name,$row->column_link);
}
return $columnByName;
}
//in controller call the model and pass the return array to view
in view
$V){
echo "".strtoupper($k)."";
foreach($v as $links){
echo "".$links[0]."";
}
echo ''
}
?>
use css to decorate to get exact match as you are looking

Categories