PHP Array not accessible - php

Basically, i'm trying to get users data from a database using a class i found, it's parsing all data inside an array as shown here from the following function :
public function Get($field = NULL) {
if ($field == NULL)
{
$data = array();
while ($row = mysql_fetch_array($this->last_query))
{
$data[] = $row;
}
}
else
{
$row = mysql_fetch_array($this->last_query);
$data = $row[$field];
}
return $data;
}
Here's the PHP code i'm using to get the call this function
if($_SERVER['REQUEST_METHOD'] == 'POST'){
if($_SESSION['csrfToken'] == $_POST['csrfToken']) {
$email = $_POST['email'];
$password = $Security->Salt($Security->secParam($_POST['password']));
$DB->Query("SELECT * FROM `table` WHERE `email` = '$email' AND `password` = '$password'");
if($DB->num_rows() > 0) {
$results = $DB->Get();
} else {
echo "Account not found";
}
}
}
If i do a var_dump on $results it shows the following
array(1) {
[0]=> array(8) {
[0]=> string(1) "1" ["id"]=> string(1) "1"
[1]=> string(35) "email#email.com" ["email"]=> string(35) "email#email.com"
[2]=> string(32) "4f14dfef1efe0de64e2b176eac6051cd" ["password"]=> string(32) "4f14dfef1efe0de64e2b176eac6051cd"
[3]=> string(1) "1" ["status"]=> string(1) "1"
}
}
how can i access this data ? I've tried calling it by doing the following
$email = $results['email'];
echo $email;
But it's not displaying anything ?

Even though there's only one result in this instance (I guess?) the array supports multiple.
So find the first result, then take the email from that:
echo $results[0]['email'];
// ^^^^^^^^^^^
// first result

You need to tracking how arrays works. First you have array(1) and then into array another vars such as "email" or 1.
array(1) { <---- THIS IS ARRAY OCCURED FOR FIRST "0" ARRAY.
What's about
this
\/
echo $results[0]["email"]; ?

if($_SERVER['REQUEST_METHOD'] == 'POST' && $_SESSION['csrfToken'] == $_POST['csrfToken']) {
$password = $Security->Salt($Security->secParam($_POST['password']));
$password = $DB->quoteStr($password);
$email = $DB->quoteStr($_POST['email']);
$DB->Query("SELECT * FROM `table` WHERE `email` = $email AND `password` = $password");
return $DB->GetRow();
}
public function GetRow() {
return mysql_fetch_array($this->last_query);
}
public function quoteStr($str) {
return "'".mysql_real_escape_string($str)."'";
}

Marin Sagovac question is the answer.
To break it down a little more, your var_dump output shows that $results is a nested array. The first part of the output:
array(1) {
[0]=>
shows that $results consists of an array containing 1 element, at index 0, since that's where PHP starts indexing. This is the $results[0] part of Marin's response.
The element 0 of the $results array consists of an array with 8 elements.
[0]=>array(8) {
[0]=> string(1) "1" ["id"]=> string(1) "1"
[1]=> string(35) "email#email.com" ["email"]=> string(35) "email#email.com"
Even though there are only 4 actual results, index 1-4, each one exists twice so that they can either be accessed by index or by its key. Arrays that can be accessed by a unique key, as opposed to an index, are known as associative arrays.
So, in this case, either will return the same value:
echo $results[0]["email"];
echo $results[0][1];
The print_r function would also work, instead of var_dump.

Related

PHP Arrays - Merge two arrays where a value is added together

I need some more help regarding PHP Arrays and the issue I am having. I have an array like this: -
array(2) {
[0]=>
array(2) {
[0]=>
array(2) {
["count"]=>
string(3) "100"
["id"]=>
int(46)
}
[1]=>
array(2) {
["count"]=>
string(3) "300"
["id"]=>
int(53)
}
}
[1]=>
array(1) {
[0]=>
array(2) {
["count"]=>
string(3) "200"
["id"]=>
int(46)
}
}
}
However, I would like it to look more like this as array: -
array(2) {
[0]=>
array(2) {
["count"]=>
string(3) "300" <--- This has been added from Array 1 and 2
["id"]=>
int(46)
}
[1]=>
array(2) {
["count"]=>
string(3) "300"
["id"]=>
int(53)
}
}
Basically if the same id is in both areas I want the count number to be added to each other but if it's not then it needs to just be left alone and included in the array.
I have used a number of array functions such as array_merge and array_push but I am running out of ideas of how this could work. I have also started working on a foreach with if statements but I just got myself completely confused. I just need a second pair of eyes to look at the issue and see howe it can be done.
Thanks again everyone.
Should work with something like this:
$idToCountArray = array(); //temporary array to store id => countSum
array_walk_recursive($inputArray, function($value,$key) { //walk each array in data structure
if(isset(value['id']) && isset($value['count'])) {
//we have found an entry with id and count:
if(!isset($idToCountArray[$value['id']])) {
//first count for id => create initial count
$idToCountArray[$value['id']] = intval($value['count']);
} else {
//n'th count for id => add count to sum
$idToCountArray[$value['id']] += intval($value['count']);
}
}
});
//build final structure:
$result = array();
foreach($idToCountArray as $id => $countSum) {
$result[] = array('id' => $id, 'count' => ''.$countSum);
}
Please note that I have not testet the code and there is probably a more elegant/performant solution.
You could use something like this:
$end_array = array();
function build_end_array($item, $key){
global $end_array;
if (is_array($item)){
if( isset($item["id"])){
if(isset($end_array[$item["id"]]))
$end_array[$item["id"]] = $end_array[$item["id"]] + $item["count"]*1;
else
$end_array[$item["id"]] = $item["count"]*1;
}
else {
array_walk($item, 'build_end_array');
}
}
}
array_walk($start_array, 'build_end_array');
Here is a fiddle.
Thank you ever so much everyone. I actually worked it by doing this: -
$fullArray = array_merge($live, $archive);
$array = array();
foreach($fullArray as $key=>$value) {
$id = $value['id'];
$array[$id][] = $value['count'];
}
$result = array();
foreach($array as $key=>$value) {
$result[] = array('id' => $key, 'count' => array_sum($value));
}
return $result;

mysqli results not filling in values

I've been trying to create an array from a mysqli query that creates a new class 'Book'. When I run this code, it returns the correct number of rows that I have in my database, but it won't display any of the values in the rows. Definitely a newb to a lot of this stuff, any help is really appreciated! Here's the code I'm running. If I just put in a pre-populated array, the code all works great. My problem is getting the values from the database into this array.
$db = new db();
$conn = $db->connect();
$sql = "SELECT * FROM users";
$result = mysqli_query($conn, $sql);
$thearray = array();
while($array_ar = mysqli_fetch_array($result)){
$thearray[] = array(
$array_ar['username'] => new Book($array_ar['username'], $array_ar['first_name'], $array_ar['last_name']),
);
}
echo 'Rows found: ' . mysqli_num_rows($result);
return $thearray;
Ok, so I var_dump($thearray); and it gives me a multidimensional array, which is why it's returning empty values. I think I need it to return an associative array? Here's what it var_dump($thearray); returns:
array(4) {
[0]=> array(1) {
["joshua"]=> object(Book)#6 (3) {
["title"]=> string(6) "joshua" ["author"]=> string(6) "Joshua" ["description"]=> string(9) "Lundquist"
}
}
[1]=> array(1) {
["matthew"]=> object(Book)#7 (3) {
["title"]=> string(7) "matthew" ["author"]=> string(4) "Matt" ["description"]=> string(3) "Alm"
}
}
[2]=> array(1) {
["roger"]=> object(Book)#8 (3) {
["title"]=> string(5) "roger" ["author"]=> string(5) "Roger" ["description"]=> string(9) "Lundquist"
}
}
[3]=> array(1) {
["norm"]=> object(Book)#9 (3) {
["title"]=> string(4) "norm" ["author"]=> string(4) "Norm" ["description"]=> string(5) "Shupe"
}
}
}
Next I thought I would take a look at what the var_dump(); for my hard-coded array looks like, and it output this (this one works):
array(3) {
["Jungle Book"]=> object(Book)#3 (3) {
["title"]=> string(11) "Jungle Book" ["author"]=> string(10) "R. Kipling" ["description"]=> string(15) "A classic book."
}
["Moonwalker"]=> object(Book)#4 (3) {
["title"]=> string(10) "Moonwalker" ["author"]=> string(9) "J. Walker" ["description"]=> string(7) "another"
}
["PHP for Dummies"]=> object(Book)#5 (3) {
["title"]=> string(15) "PHP for Dummies" ["author"]=> string(14) "Some Smart Guy" ["description"]=> string(18) "and the final one."
}
}
It makes sense to me what's happening, but I'm not sure how to fix my code. Thank you for the help!
Don't Panic's answer got me looking in the right direction. I needed to create an associative array, not a multidimensional array. At first I was accidentally creating the multidimensional array by setting $thearray equal to "array();". By removing that, it filled in the values correctly. Thanks again for the help!
$db = new db();
$conn = $db->connect();
$sql = "SELECT * FROM users";
$result = mysqli_query($conn, $sql);
$thearray = array();
while($array_ar = mysqli_fetch_array($result)){
$title = $array_ar['username'];
$author = $array_ar['username'];
$description = $array_ar['username'];
$thearray[] = $title = new Book($title, $author, $description);
}
var_dump($thearray);
echo 'Rows found: ' . mysqli_num_rows($result);
return $thearray;
I think this is the problem.
$thearray[] = array(
$array_ar['username'] => new Book(
$array_ar['username'], $array_ar['first_name'], $array_ar['last_name']),
);
It looks like the differences between what you're getting and what you want is 1) You're wrapping the input to $thearray in an extra array() layer, and 2) You won't get string keys like you have in your hard-coded array if you just add the items using [].
Try it like this instead:
// use the username as a key, since that is what it looks like you're using as the 'title'
$thearray[$array_ar['username']] = new Book(
$array_ar['username'], $array_ar['first_name'], $array_ar['last_name']);

Remove duplicate array where key->value appears twice - leave just one array

Removing an array if there is a duplicate in inner array for example - As we see there is [0]['user'] and its 1, the same appears in the array 1, my desired array would only contain one of the arrays it doesn't matter which one - also would be nice if I would get a returned message that there were duplicates, the array length can vary from 1 to 10 for example. I tried some codes provided already here on stackoverflow for unique multidementional arrays but non seems to be working for me.
And this is the html method. The users can duplicate because of selection of the same user name
array(3) {
[0]=>
array(6) {
["user"]=>
string(1) "1"
["role"]=>
string(1) "1"
["can_edit"]=>
NULL
["can_read"]=>
NULL
["can_execute"]=>
NULL
["is_admin"]=>
NULL
}
[1]=>
array(6) {
["user"]=>
string(1) "1"
["role"]=>
string(1) "2"
["can_edit"]=>
NULL
["can_read"]=>
NULL
["can_execute"]=>
NULL
["is_admin"]=>
NULL
}
}
Code used for the example output
foreach ($this->input->post() as $key => $value)
{
if(preg_match("/^user.{1,2}$/",$key)>0) {
$postvars[] = $key;
}
if(preg_match("/^user.{1,2}$/",$key)>0) {
$postvalues[] = $value;
}
}
$filterArray = array_combine($postvars, $postvalues);
function array_unique_multidimensional($input)
{
$serialized = array_map('serialize', $input);
$unique = array_unique($serialized);
return array_intersect_key($input, $unique);
}
foreach (array_unique_multidimensional($postvars) as $key)
{
preg_match("|\d+|", $key, $m);
$user = $filterArray[$key];
$role = $this->input->post('role'.$m[0]);
$can_edit = $this->input->post('can_edit'.$m[0]);
$can_read = $this->input->post('can_read'.$m[0]);
$can_execute = $this->input->post('can_execute'.$m[0]);
$is_admin = $this->input->post('is_admin'.$m[0]);
$records[] = array('user' => $user,'role'=>$role,'can_edit'=>$can_edit,'can_read' =>$can_read,'can_execute' =>$can_execute,'is_admin'=>$is_admin);
}
var_dump($records);
var_dump(array_unique_multidimensional($records));

SQLite3 returns both indexed and associative array

I have a SQLite query in PHP:
$database = new SQLite3("database.db");
$statement = $database->prepare("SELECT * FROM table");
$result = $statement->execute();
$table = array();
while ($row = $result->fetchArray()) {
array_push($table, $row);
}
var_dump($table);
and it outputs
array(2) {
[0]=> array(4) {
[0]=> int(1)
["event"]=> int(1)
[1]=> string(2) "A1"
["code"]=> string(2) "A1"
}
[1]=> array(4) {
[0]=> int(5)
["event"]=> int(5)
[1]=> string(2) "A2"
["code"]=> string(2) "A2"
}
}
Which is the correct data, but it's outputting all of the information twice: one with an index attached, and one with the column name. Is there any way to pick one or the other? This program needs to be very memory efficient as it will be expanded to having thousands of rows.
This will give you a regular mysql-style assoc array output,
$db = new SQLite3('dbs');
$result = $db->query("SELECT * FROM table");
$assoc_array = array();
while ($dbs_row = $result->fetchArray(SQLITE3_ASSOC)) {
$assoc_array[] = $dbs_row;
}
SQLite's fetchArray function can take a mode parameter. You can use SQLITE3_ASSOC, SQLITE3_NUM, or SQLITE3_BOTH for the desired effect. I guess I should've looked at the documentation before I posted :)

I got Undefined index: reading recursively an array

I'm going to be crazy, I can't understand what is the problem.
I have this array:
array(2) {
[0]=>
array(4) {
["id"]=>
string(1) "1"
["parent_id"]=>
NULL
["name"]=>
string(7) "Events"
["children"]=>
array(2) {
[0]=>
array(3) {
["id"]=>
string(1) "2"
["parent_id"]=>
string(1) "1"
["name"]=>
string(9) "Concerts"
}
}
}
[1]=>
array(4) {
["id"]=>
string(1) "4"
["parent_id"]=>
NULL
["name"]=>
string(7) "Music"
["children"]=>
array(3) {
[0]=>
array(3) {
["id"]=>
string(1) "5"
["parent_id"]=>
string(1) "4"
["name"]=>
string(4) "Rock"
}
}
}
}
and I try to print with this recursive function:
public function printTree($tree) {
$result = "";
if(!is_null($tree) && count($tree) > 0) {
$result .= '<ul>';
foreach($tree as $node) {
$result .= '<li>Cat: '.$node['name'];
$subtree = array($node['children']);
$this->printTree($subtree);
$result .= '</li>';
}
$result .= '</ul>';
}
return $result;
}
I get an "Undefined index: name" error.
Do I need to declare name? how?
Is the array with incorrect syntax?
If I comment the recursive call
$subtree = array($node['children']);
$this->printTree($subtree);,
then $node['name'] isn't undefined and the code works, but of course with only with one level of depth.
SOLVED: (Thanks all guys!)
public function printTree($tree) {
$result = "";
if(is_array($tree) && count($tree) > 0) {
$result .= '<ul>';
foreach($tree as $node) {
$result .= '<li>Cat: '.$node['name'];
if (isset($node['children'])) {
$result .= $this->printTree($node['children']);
}
$result .= '</li>';
}
$result .= '</ul>';
}
return $result;
}
You are pushing $node['children'] into an additional array. That way you are not dealing with the subarray of this node (which has a name later on), but you have another layer of array.
Skip this array layer, remove it.
Also note that !is_null() isn't really a nice check if you then want to use that variable as an array. Check for is_array() instead, because strings and other scalar values will return count>0 as well - they return 1. Only NULL returns count=0.
You will have to append the results returned by the consecutive calls to printTree() for child nodes to the $result.
$result .= $this->printTree($node['children']);
:)
First of all, you want to enclose the $subtree-stuff into an if-condition checking for the existence of the key 'children', because as it is now, you have created an infinite loop of recursive calls to printTree(), but you only want to do this, if the key 'children' exists.
Second, I guess you want to add $result .= in front of $this->printTree($subtree);, otherwise the return value will simply be discarded.
Third, don't do $subtree = array($node['children']);. $node['children'] already is an array, so this adds another level to the array, which makes the recursion break.
So, the final function should look something like this:
public function printTree($tree) {
$result = '';
if(!is_null($tree) && count($tree) > 0) {
$result .= '<ul>';
foreach($tree as $node) {
$result .= '<li>Cat: '.$node['name'];
if (isset($node['children'])) {
$subtree = $node['children'];
$result .= $this->printTree($subtree);
}
$result .= '</li>';
}
$result .= '</ul>';
}
return $result;
}
Edit: Whoops, was too slow there, the others also found the three problems here :)

Categories