I have a question about displaying a variable that is in the an array of another array. Below is an example of a var_dump() of my $_POST variable. As you can see I have an array.. and another array in that array.. and another array in that array.. I actually need a variable from each of the layers.
Array(
[type] => note
[date_time] => 17-01-01
[initiated_from] => admin
[initiated_by] => admin
[list] => 0
[note] => THIS IS A TEST
[contact] => Array
(
[id] => 250
[email] => TEST#TESTING.COM
[first_name] => TEST
[last_name] => McTESTER
[phone] => (777)777-7777
[ip] => 0.0.0.0
[tags] => buyer, requote, followup1, delete
[fields] => Array
(
[3] => TESTER#TESTER.com
[5] => TESTING TESTER
[10] => STATE
[11] => CITY
[12] => COUNTY
[6] => PHONE NUMBER
[8] => www.test.com
[9] => MORE TESTS
)
Here is my code that I tried.
$sql_note="INSERT INTO customer_notes(customer_email,note,added_by,note_date) VALUES('$_POST[contact][email]','$_POST[note]','$_POST[contact][fields][3]','$note_date')";
(Ignore the $note_date) So these are the three things I am trying to get..
$_POST[note]
$_POST[contact][email]
$_POST[contact][fields][3]
I get the first one just fine but I get ARRAY[EMAIL] and ARRAY[FIELDS][3]
You are using variable expansion incorrectly:
$foo = array();
$foo['one']['two'] = 'OK';
echo "Value is $foo[one][two]\n"; // Value is Array[two]
echo "Value is {$foo[one][two]}\n"; // Value is OK
... and in the wrong job. Your query should look like this:
$sql_note = "INSERT INTO customer_notes(customer_email, note, added_by, note_date)
VALUES (?, ?, ?, ?)";
... and values should be passed in an array. Injecting raw untrusted data into SQL code is terribly messy to write and leads to SQL injection vulnerabilities. Please check the documentation for your database library.
Related
I am generating PHP arrays from a MySQL database, with the output to be converted to JSON using json_encode (ultimately for use with Twitter typeahead).
Based upon everything I've read about PHP arrays, I had expected the select query to generate - for any record - just a single key-value pair for each column.
Instead, I seem to be getting both a name-value pair and a key-value pair.
For instance, for a table with 5 columns, the set of values FOR A SINGLE RECORD are in the form:
[fieldname1] => value1 [0] => value1
[fieldname2] => value2 [1] => value2
[fieldname3]] => value3 [2] => value3
[fieldname4]=> value4 [3] => value4
[fieldname5] => value5 [4] => value5
When I use json_encode it generates the following JSON string for that record - which is twice as long as it needs to be because I am getting both the name-value pair and the key-value pair (so the the value is repeated very line).
"fieldname1":"value1","0":"value1",
"fieldname2":"value2","1":"value2",
"fieldname3":"value3","2":"value3",
"fieldname4":"value4","3":"value4",
"fieldname5":"value5","4":"value5",
What I would prefer is just the 'fieldname1' => 'value1' or its json equivalent.
Here is an example of the code I use in PHP to select the data from the database.
<?php
$sql = "SELECT * FROM `tr_trades_anzsco` WHERE `trade_alias_id` > 898";
$trade = $dbh->query($sql);
foreach($trade as $trade):
$trade_alias_id = $trade['trade_alias_id'];
$trade_alias = trim($trade['trade_alias']);
print_r($trade);
endforeach;
?>
Here is the resultant dataset for just three records.
Array ( [trade_alias_id] => 899 [0] => 899 [trade_alias] => Boilermaker [1] => Boilermaker [ANZSCO_title] => Structural Steel And Welding Trades Workers [2] => Structural Steel And Welding Trades Workers [ANZSCO_code] => 322300 [3] => 322300 [source] => Raj [4] => Raj ) Array ( [trade_alias_id] => 900 [0] => 900 [trade_alias] => Welder [1] => Welder [ANZSCO_title] => Structural Steel And Welding Trades Workers [2] => Structural Steel And Welding Trades Workers [ANZSCO_code] => 322300 [3] => 322300 [source] => Tom [4] => Tom ) Array ( [trade_alias_id] => 901 [0] => 901 [trade_alias] => Rigger [1] => Rigger [ANZSCO_title] => Construction Rigger [2] => Construction Rigger [ANZSCO_code] => 821711 [3] => 821711 [source] => Jack [4] => Jack )
Finally, here is the json string for the final record only (broken up so the structure is more easily visible).
Array ( [0] => Array (
[trade_alias_id] => 901 [0] => 901
[trade_alias] => Rigger [1] => Rigger
[ANZSCO_title] => Construction Rigger [2] => Construction Rigger
[ANZSCO_code] => 821711 [3] => 821711
[source] => Jack [4] => Jack )
)
The duplicate values matter considerably for performance reasons - because the data is to be extracted for use on mobile devices (with Twitter TypeAhead and possibly AngulularJS). Our datasets are already very large ... so twice the json will double the time for fetching the data.
Key question: How I can remove the duplicates either at the PHP stage OR the json_encode stage so as to generate ONLY a name-value pair but not both a name-value and a key-value pair?
Thank you!
Presuming you are using pdo:
$trade = $dbh->query($sql, PDO::FETCH_ASSOC);
You can unset it if the key is int
foreach($trade as $key=>$value) {
if(!is_int($key) {
unset($trade[$key]);
}
}
Hope this helps :D
I am retrieving a multidimensional php array (I think) from an API, now all of the values return perfectly and when I dump the array with print_r I get this:
Event Object
(
[title] => test
[link] => google.com
[updated] => 2013-03-06T12:08:56.521-05:00
[id] => test
[name] => Copy of Copy of Copy of Mar 05, 2013 - TEST4
[description] =>
[registered] => 2
[createdDate] => 2013-03-06T12:08:56.521-05:00
[status] => COMPLETE
[eventType] => OTHER
[eventLocation] => EventLocation Object
(
[location] => test
[addr1] => test
[addr2] =>
[addr3] =>
[city] => madrid
[state] => andalucia
[country] =>
[postalCode] => 06103
)
[registrationUrl] => https://google.com
[startDate] => 2013-03-07T13:00:00-05:00
[endDate] => 2013-03-07T13:00:00-05:00
[publishDate] => 2013-03-06T12:11:15.958-05:00
[attendedCount] => 0
[cancelledCount] => 0
[eventFeeRequired] => FALSE
[currencyType] => USD
[paymentOptions] => Array
(
)
[registrationTypes] => Array
(
[0] => RegistrationType Object
(
[name] =>
[registrationLimit] =>
[registrationClosedManually] =>
[guestLimit] =>
[ticketing] =>
[eventFees] => Array
(
)
)
)
)
Now bumbling through wit my basic PHP i have found that i can list all of the first array items from [title] to [eventType] like this:
<?php
// get details for the first event returned
$Event = $ConstantContact->getEventDetails($events['events'][0]);
reset($Event);
while (list($key, $value) = each($Event)) {
echo "$key => $value \r\n<br/>";
}
?>
my question: All I need to do it retrieve [title] and [startDate] I don't need the rest now I could just hide the rest using Js and css but i am sure i am just being an idiot and there is an easier way to traverse this array so it only spits out the two values i need.
How do i do this?
You do not have to traverse the whole object. Just access the properties you want:
$title = $Event->title;
$startDate = $Event->startDate;
// or
echo $Event->title;
echo $Event->startDate;
It's actually an object - not an (associative) array!
What's the difference?
An object is an instance of a class. A class has methods and attributes (member variables).
Unlike C++ or some other OOP languages, you can define attributes dynamically without declaring them in the class declaration.
An array is simply a container for keys and their values.
It seems that it's not an array but an object so something like this:
echo $Event->title;
echo $Event->startDate;
Is it ...
<?php
// get details for the first event returned
$Event = $ConstantContact->getEventDetails($events['events'][0]);
reset($Event);
echo $Event->$title . "<br/>";
echo $Event->$startDate . "<br/>";
?>
? Or am I too simple?
I have a simple user table with columns: username, password, email, name, surname, birthdate, address and city. the first three are mandatory but the rest of them can be null.
I am connecting to the database and fetch rows in an array and print it.
$dbc=mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
$sql = "select * from user";
$data = mysqli_query($dbc, $sql) or die("query exec error");
//$json = array();
if(mysqli_num_rows($data)){
while($row=mysqli_fetch_array($data)){
//$json['Kullanici'][]=$row;
print_r($row);
echo "<br /><br />";
}
}
mysqli_close($dbc);
//echo json_encode($json);
But the output is like this:
Array ( [0] => ayse [username] => ayse [1] => b1b3773a05c0ed0176787a4f1574ff0075f7521e [password] => b1b3773a05c0ed0176787a4f1574ff0075f7521e [2] => ayse#hotmail.com [email] => ayse#hotmail.com [3] => [name] => [4] => [surname] => [5] => 0000-00-00 [birthdate] => 0000-00-00 [6] => [address] => [7] => istanbul [city] => istanbul )
Array ( [0] => baris [username] => baris [1] => 7c4a8d09ca3762af61e59520943dc26494f8941b [password] => 7c4a8d09ca3762af61e59520943dc26494f8941b [2] => bakkurt#hotmail.com [email] => bakkurt#hotmail.com [3] => Barış [name] => Barış [4] => [surname] => [5] => 0000-00-00 [birthdate] => 0000-00-00 [6] => [address] => [7] => [city] => )
The question is why there is both [0]=>baris and [username] => baris. I was expecting only the username=>baris. Was I wrong? Where am i missing?
If i solve this problem, I will convert the array to json by removing comments.
It's not a problem, if you look at the PHP documentation for the mysqli_fetch_array() function, it accepts a parameter resulttype; it determines whether to return records as arrays with numeric indices alone, associative indices alone or both (which is what you have).
By default, the function uses MYSQLI_BOTH.
To get as numeric indices alone:
while($row=mysqli_fetch_array($data, MYSQLI_NUM)){
//this will always return with numeric indices alone
}
For more information check here PHP mysqli_fetch_array
if you need only username => baris
Try mysqli_fetch_assoc.
Courtesy - http://www.php.net
It returns an associative array of strings representing the fetched row
in the result set, where each key in the array represents the name of
one of the result set's columns or NULL if there are no more rows in
resultset.
I think what you are looking for is the resulttype parameter. Have a look at this page: mysqli_result::fetch_array
You probably want to call the fetch_array function like this:
mysqli_fetch_array($data, MYSQLI_ASSOC)
Try using mysqli_fetch_assoc() instead of mysqli_fetch_array().
mysqli_fetch_array() fetch data as both enumerated and associative, so if you only need associative array use mysqli_fetch_array().
You can also read the documentation if you want to know something more about it.
I want to store the contents of a specific database into an array, grouped by their primary keys. (Instead of the useless way PDO fetchAll() organises them).
My current code:
$DownloadsPDO = $database->dbh->prepare("SELECT * FROM `downloads`");
$DownloadsArray = $DownloadsPDO->execute();
$DownloadsArray = $DownloadsPDO->fetchAll();
Which then outputs:
Array ( [0] => Array ( [id] => 0 [0] => 0 [path] => /xx-xx/testfile.zip [1] => /xx-xx/testfile.zip [name] => Test Script [2] => Test Script [status] => 1 [3] => 1 ) [1] => Array ( [id] => 1 [0] => 1 [path] => /xx-xx/test--file.zip [1] => /xxxx/testfile.zip [name] => New Script-UPDATE [2] => New Script-UPDATE [status] => 1 [3] => 1 ) )
I was considering to use PDO::FETCH_PAIR, however I will be very soon expanding the amount of data I want to be able to use on this script. This works currently, but when I start to expand the amount of downloads and more clients come into play, obviously the way the data is grouped causes an issue.
Is it possible for me to group each array by their primary key (which is id)?
You can just use
$results = array_map('reset', $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC))
PDO::FETCH_GROUP|PDO::FETCH_ASSOC returns an array of arrays. The first column is used as the key, and then within key is an array of all the results for that key. However, in our scenario each key will only contain 1 row. reset() returns the first element in array, thus eliminating 1 level of nesting.
This should yield what you are looking for :
$results = $pdos->fetchAll(\PDO::FETCH_UNIQUE|\PDO::FETCH_ASSOC);
I decided to just loop through the results with fetch() and enter them into an array as I go along, this is the code I have used and it works just fine:
$DownloadsPDO = $database->dbh->query("SELECT * FROM `downloads`");
$Array = array();
while ($d = $DownloadsPDO->fetch()) {
$Array[$d['id']]["id"] = $d['id'];
$Array[$d['id']]["name"] = $d['name'];
$Array[$d['id']]["path"] = $d['path'];
}
// Outputs
Array ( [1] => Array ( [id] => 1 [name] => Test Script [path] => /xxxx/testfile.zip ) [2] => Array ( [id] => 2 [name] => New Script-UPDATE [path] => /xxxx/testfile.zip ) )
Which uses the primary key (being id) as the name for the array key, and then adds the data into it.
Thought I would add this as the answer as this solved it, thanks to the guys that helped out and I hope this is helpful to anyone else hoping to achieve the same thing.
I'd like to point out the only solution that works for me:
fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE|\PDO::FETCH_ASSOC);
Beware that this will strip the first column from the resultset. So the query must be:
SELECT id_keyname AS arrkey, id_keyname, .... FROM ...
I'm still suggesting you to loop using fetch() method. Otherwise, you can use array_reduce() to iterate over the array. A sample on codepad is here.
The code(in human readable form) will be:
$myFinalArray = array_reduce($myInputArray, function($returnArray, $temp) {
$temp2 = $temp['id'];
unset($temp['id']);
$returnArray[$temp2] = $temp;
return $returnArray;
}
);
So, my question is; is it possible for me to group each array by their
primary key (which is id)
Off course, you have 2 options here: Either to change the query or parse a result-set.
So, I'm sure you don't want to change query itself, so I'd go with parsing result-set.
Note:
You should use prepared SQL statements when they make sense. If you want to bind some parameters then its OKAY. But in this case, you only want get get result-set, so prepare() and fetch() will be kinda overdo.
So, you have:
Array ( [0] => Array ( [id] => 0 [0] => 0 [path] => /xx-xx/testfile.zip [1] => /xx-xx/testfile.zip [name] => Test Script [2] => Test Script [status] => 1 [3] => 1 ) [1] => Array ( [id] => 1 [0] => 1 [path] => /xx-xx/test--file.zip [1] => /xxxx/testfile.zip [name] => New Script-UPDATE [2] => New Script-UPDATE [status] => 1 [3] => 1 ) )
And you want:
Array( [id] => Array('bar' => 'foo') ....)
Well, you can do something like this:
$stmt = $database->dbh->query("SELECT * FROM `downloads`");
$result = array();
foreach($stmt as $array){
$result[$array['id']] = $array;
}
print_r($result); // Outputs: Array(Array('id' => Array(...)))
I have a php script does this:
Put UPC into form
Submit form
Check to see if the UPC already exists in my database
If yes, fetch it from MySQL database
If not, fetch it from an external server, add it to MySQL database for future use
Display results
It works fine, but I'd like the variable to look exactly the same wether it comes from the MySQL cache, or the external server.
When I print it from the server, it looks like this:
Output:
[upc] => 066721020215
[pendingUpdates] => 0
[status] => success
[ean] => 0066721020215
[issuerCountryCode] => us
[found] => 1
[description] => Christie - Original Ritz Crackers
[message] => Database entry found
[size] => 225 g
[issuerCountry] => United States
[noCacheAfterUTC] => 2012-08-06T12:23:58
[lastModifiedUTC] => 2009-04-06T01:51:08
However, When I print the array from MySQL, it looks like this:
$result = mysql_query("SELECT * FROM UPC WHERE `upc` = '$codes[0]'");
$data = mysql_fetch_array($result);
echo "<pre>" . print_r($data, true) . "</pre>";
Output:
[0] => 066721020215
[upc] => 066721020215
[1] => 0
[pendingUpdates] => 0
[2] => success
[status] => success
[3] => 0066721020215
[ean] => 0066721020215
[4] => us
[issuerCountryCode] => us
[5] => 1
[found] => 1
[6] => Christie - Original Ritz Crackers
[description] => Christie - Original Ritz Crackers
[7] => Database entry found
[message] => Database entry found
[8] => 225 g
[size] => 225 g
[9] => United States
[issuerCountry] => United States
[10] => 2012-08-06
[noCacheAfterUTC] => 2012-08-06
[11] => 2009-04-06
[lastModifiedUTC] => 2009-04-06
I realize it's more or less a cosmetic difference (and an array twice as big as it needs to be), but how would I go about easily removing the 0,1,2,3,etc identifiers without looping through the array creating and manually creating a new one? Is there a function that would remove the numbered identifiers?
You need to use mysql_fetch_array($result, MYSQL_ASSOC) or mysql_fetch_assoc($result).
See http://php.net/manual/en/function.mysql-fetch-array.php and http://www.php.net/manual/en/function.mysql-fetch-assoc.php for more details.
Note that both are discouraged, as they have been replaced by the new(ish) mysqli functions: http://uk.php.net/manual/en/book.mysqli.php
Change the line:
$data = mysql_fetch_array($result);
to:
$data = mysql_fetch_assoc($result);
mysql_fetch_assoc returns the data from the db as an associative array - mysql_fetch_array returns a mixed array, with both numeric and associative indexes.
See http://php.net/manual/en/function.mysql-fetch-assoc.php