How to add array to array in PHP - php

So I thought this would be easy, but try as I might various methods of appending values to an array in PHP, I always get NULL.
$sites = array();
$sites[0] = $_POST['site0'];
foreach($sites as $site) {
var_dump($site);
}
$_POST['site0'] is an HTML form array, containing 11 keys and values. I get a invalid argument error for line 3. Any reason why this would occur?

Probably, $_POST['site0'] is null or empty.
You could push the value to the $sites array doing so:
$sites[] = $_POST['site0'];
The value will be pushed to the end of the array.

It's really work. Just check your
$_POST['site0'];
and try add
$sites[1] = 'spam';

Your code works for me (see codepad):
Code
$_POST['site0'] = 'foobar';
$sites = array();
$sites[0] = $_POST['site0'];
var_dump($sites); // returns NULL
Result
array(1) {
[0]=>
string(6) "foobar"
}
Try to var_dump($_POST); to see what's actually contained in $_POST.

Related

Can't use JSON array in a php loop

i have a json file, that has to be parsed in a loop.
i cant seem to succeed
JSON:
{"IMD":{"url":"http:\/\/www.google.com","timeOut":1515155361},"cvH":{"url":"http:\/\/www.google.com","timeOut":1515155364}}
PHP:
<?php
$linkyValues="./linky.json";
if (file_exists($linkyValues)) {
$fileStream = fopen($linkyValues, 'r');
$fileValue=json_decode(fread($fileStream, filesize($linkyValues)));
fclose($fileStream);
echo count($fileValue);//Always 1!
for($i=0;$i<count($fileValue);$i++){
$timeout=$fileValue->item($i)->timeOut;
if(time()>=$timeout){
unset($fileValue[$i]);
}
}
$fileStream = fopen($linkyValues, 'w');
fwrite($fileStream, json_encode($fileValue));
fclose($fileStream);
}
?>
my problem is that count($fileValue) is always 1.
Output of var_dump($fileValue):
object(stdClass)#2 (2) {
["IMD"]=>
object(stdClass)#1 (2) {
["url"]=>
string(21) "http://www.google.com"
["timeOut"]=>
int(1515155361)
}
["cvH"]=>
object(stdClass)#3 (2) {
["url"]=>
string(21) "http://www.google.com"
["timeOut"]=>
int(1515155364)
}
}
it looks like an array to me...
JSON does not support the concept of an associative array, but stores such maps as objects instead.
Your JSON file contains such an object. For PHP this means, that it can either import it as an stdClass ( object ) or as an associatiave array.
This is decided by the json_decode's second parameter, that is either TRUE to read the object as an associative array, or FALSE to read it as an object.
Therefore this will fix your problem:
$fileValue = json_decode(fread($fileStream, filesize($linkyValues)), TRUE);
json_decode documentation
In addition to that, your code has problems with iterating the array. You use $fileValue->item($i) as well as $fileValue[$i], while you have an associative array.
You work with it as if it was an indexed array, while it is an associative array, which means it has keys instead of indices, that identify the values in your array.
The propper way to iterate an associative array is with foreach, like deomstrated belo:
foreach($fileValue as $key => $value) {
if (time() >= $value['timeOut']) {
unset($fileValue[$key]);
}
}
Yet, since you only want to remove specific values, you can use array_filter as well:
$fileValue = array_filter($fileValue, function($value){
return time() < $value['timeOut'];
});
array_filter will then take care of removing the specified fields from your array, so you do not have to unset them manually.
You can use :
count((array)$fileValue);
You're mixing up arrays and objects here.
count() can only be used on arrays, however you can cast an object to array to achieve the same thing.
$fileValue[$i] is a method to access an array, which won't work with your json object.
I see a solution already is to just change your object to an array so I'd like to offer the solution if you wanted to stick with objects.
$linkyValues="./linky.json";
if (file_exists($linkyValues)) {
$fileStream = fopen($linkyValues, 'r');
$fileValue=json_decode($jsonString);
fclose($fileStream);
//Cast the object to an array to get the count, but count isn't really requierd
echo count((array)$fileValue);
//loop through the object
foreach($fileValue as $key=>$fv){
//pull the timeout
$timeout=$fv->timeOut;
//do the check
if(time()>=$timeout){
//remove the timeout from the object
unset($fileValue->$key);
}
}
$fileStream = fopen($linkyValues, 'w');
fwrite($fileStream, json_encode($fileValue));
fclose($fileStream);
}
?>

Can't assess an array element after building array - a var_dump confirms element is there

I am writing some login code for an external app.
Currently it is sending information via GET. The information is encoded, the server decodes the info and builds into a decoded array which I can use to auth the user.
The issue is for some reason I can't access the array element, when I know it's there. I use a var_dump to confirm.
error_reporting(E_ALL);
function getNonDecodedParameters(& $a) {
foreach (explode ("&", $_SERVER["QUERY_STRING"]) as $q) {
$p = explode ('=', $q, 2);
$a[$p[0]] = isset ($p[1]) ? $p[1] : '';
}
}
function decode_array(&$encyrptArray, &$outputArray) {
foreach($encyrptArray as $encrpyKey=>$encrpyValue) {
$newKey = decode_my_mt4_string($encrpyKey);
$newVal = decode_my_mt4_string($encrpyValue);
$outputArray[$newKey] = $newVal;
}
}
//init arrays
$inputs = array();
$decoded = array();
//manually build array from query string
//bypassing $_GET because $_GET does auto urldecode()
getNonDecodedParameters($inputs);
//decode data into new array
decode_array($inputs, $decoded);
//var dump
echo '<pre>';
var_dump($inputs);
echo '<br />';
echo 'Decoded array';
echo '<br />';
var_dump($decoded);
echo '</pre>';
//try access specific array element
printf('$decoded["cname"] = %s', $decoded['cname']);
The var_dump shows this is working, but for some reason when I call the element directly, a php error is thrown saying it doesn't exist???
array(3) {
["d3JfbG9naW4A"]=>
string(12) "dGVzdHVzZXIA"
["cGFzcwA%3D"]=>
string(12) "dGVzdHBhc3MA"
["Y25hbWUA"]=>
string(14) "REFaV0FSRQA%3D"
}
Decoded array
array(3) {
["wr_login"]=>
string(9) "testuser"
["pass"]=>
string(9) "testpass"
["cname"]=>
string(8) "DAZWARE"
}
Notice: Undefined index: cname in /home/website/test2.php on line 58
$decoded["cname"] =
I really can't think of any reason why this isn't working. Couldn't this be an issue with the server?
Thanks guys,
Just to give you back the time and follow up what happened here.
The error in the variable name was not the problem, just a typo I made here.
I was encoding with base64 and sending that data to the php script. When I used base64_decode(), it would spit out the right string, but also junk bytes that was corrupting all the variable names.
The problem was a bad base 64 encoder from the external program I was using.
Thank you all for taking the time to help me here.

Create key => value pair array only if variables are set

I have a number of items of data. Sometimes the var is not created/set, sometimes it is. This is because the var data comes from a form with optional fields.
I have created the variables only if the information is present as such:
if(!empty($_POST["user-jobtitle"])){
$idealJobTitle = $_POST["user-jobtitle"]; }
So if the field user-jobtitle is not filled in, then $idealJobTitle is not created.
I now wish to create an array with a key for each value. But I only want to add to the array if that variable exists. Otherwise, I just want to omit it.
I have written code below which I know is wrong but follows the sort of logic I am after. What is the correct way to do this? Do I really have to run through nested if statements checking if the var exists and only then pushing to the array?
$other_info = array (
"other_info" => array(
if(isset($message)){
"message" => $message
},
if(isset($salaryRange)){
"salary_range" => $salaryRange
},
if(isset($idealJobTitle)){
"ideal_job_title" => $idealJobTitle
}
if(isset($applyFor)){
"ideal_applying_for" => $applyFor
}
)
);
An expected result, if the user has not provided an ideal job title on the form, would be as such:
array(1) {
["other_info"]=>
array(3) {
["message"]=>
string(18) "my message here"
["salary_range"]=>
string(19) "£25k - £30k"
["ideal_applying_for"]=>
string(18) "Cat cuddler"
}
}
As you can see in the above, the ideal_job_title key and value are simply not present.
You should not conditionally declare variables. That's just asking for problems later on.
Unpacking values from one array into a variable and then conditionally packing them back into an array is needlessly complex. Keep your data in an array and move it around in one "package".
You can't have nested if statements within an array declaration.
The most useful way to handle this would be to use names in your form that you're also going to use later on in your $other_info array. Translating between various variable and key names throughout your code is just terribly confusing, pointless and needlessly requires a ton of additional code. In other words, why does the same piece of information need to be called user-jobtitle and $idealJobTitle and ideal_job_title in different contexts? If you'd keep it consistent, you could simply filter empty values and be done with it:
$other_info = array('other_info' => array_filter($_POST));
Yup, array_filter gets rid of empty elements without individual if statements. You can further use array_intersect_key and similar functions to further filter out keys.
If you name variables as key in the array, you can use compact function. Undefined variable will not be in array
$ar = compact("message", "salaryRange", "idealJobTitle", "applyFor");
You can use the below code :
$other_info = array();
if(isset($message)){
$other_info['other_info']["message"] = $message;
}
if(isset($salaryRange)){
$other_info['other_info']["salary_range"] = $salaryRange;
}
if(isset($idealJobTitle)){
$other_info['other_info']["ideal_job_title"] = $idealJobTitle;
}
if(isset($applyFor)){
$other_info['other_info']["ideal_applying_for"] = $applyFor;
}
You already have a code that works and puts the values in variables. Create an empty array and put the data directly in the array under various keys instead of individual variables:
$info = array();
// Analyze the input, put the values in $info at the correct keys
if (! empty($_POST["message"])) {
$info["message"] = $_POST["message"];
};
if (! empty($_POST["salaryRange"])) {
$info["salary_range"] = $_POST["salaryRange"];
};
if (! empty($_POST["idealJobTitle"])) {
$info["ideal_job_title"] = $_POST["idealJobTitle"];
}
if (! empty($_POST["applyFor"])) {
$info["ideal_applying_for"] = $_POST["applyFor"];
}
// Voila! Your data is now in $info instead of several variables
// If you want to get the structure you described in the non-working code you can do:
$other_info = array(
"other_info" => $info,
);

json encoding 2 dimension array

I have the following in php:
$query = mysql_query($sql);
$rows = mysql_num_rows($query);
$data['course_num']=$rows;
$data['course_data'] = array();
while ($fetch = mysql_fetch_assoc($query) )
{
$courseData = array(
'course_name'=>$fetch['course_name'],
'training_field'=>$fetch['training_field'],
'speciality_field'=>$fetch['speciality_field'],
'language'=>$fetch['language'],
'description'=>$fetch['description'],
'type'=>$fetch['type'],
);
array_push($data['course_data'],$courseData);
}
echo json_encode($data);
when I receive the result of this script in jquery (using post)
I log it using :
console.log(data['course_data']);
and the output is :
[Object { course_name="Introduction to C++", training_field="Engineering" , speciality_field="Software", more...}]
But I can't seem to figure out how to access the elements.
I tried
data['course_data'].course_name
data['course_data']['course_name']
Nothing worked. Any ideas
When you array_push($data['course_data'],$courseData); you are actually putting $courseData at $data['course_data'][0] and therefore you would access it in JavaScript as data['course_data'][0]['course_name'].
If you only intend to have one result, instead of array_push($data['course_data'],$courseData); you should just specify $data['course_data'] = $courseData. Otherwise, you should iterate over data['course_data'] like so:
for (i in data['course_data']) {
console.log(data['course_data'][i]['course_name']);
}
You should specify the index in the first array for instance
data['course_data'][0]['course_name'];
you could make it better if you had defined the first array just as variable not a variable within an array
$data['course_data'][0]['course_name']
should do the trick. If not please send the output of var_dump($data)
Assuming the PHP code is correct, you will receive a JSON data like:
{
"course_num":34,
"course_data":[
{
"course_name":"name_value",
....
},
....etc (other object based on SQL result)
]
}
So, if you want to access to the total number of result:
data.course_num
If you want to access to the first element of the list of result:
data.course_data[0]
If you want to access to the name of the first element of the list of result:
data.course_data[0].course_name
or
data.course_data[0]['course_name']
use jquery's parseJSON method to get all the goodies out of the json object...
http://api.jquery.com/jQuery.parseJSON/

Undefined offset while accessing array element which exists

I have an array and PHP and when I print it out I can see the values I need to access, but when I try accessing them by their key I am getting a PHP Notice. I printed the array with print_r:
Array
(
[207] => sdf
[210] => sdf
)
When I try to access the array using the index I get an undefined offset notice. Here is my code:
print_r($output);
echo $output[207]; // Undefined Offset
echo $output["207"]; // Undefined Offset
The $output array is the result of a call to array_diff_key and is input originally as JSON through an HTTP POST request.
array_keys gives me the following:
Array
(
[0] => 207
[1] => 210
)
In response to the comments:
var_dump(key($output)); outputs:
string(3) "207"
var_dump(isset($output[key($output)])); outputs:
bool(false)
See this section on converting an object to an array in the PHP Manual:
The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name.
When converting to an array from an object in PHP, integer array keys are stored internally as strings. When you access array elements in PHP or use an array normally, keys that contain valid integers will be converted to integers automatically. An integer stored internally as a string is an inaccessible key.
Note the difference:
$x = (array)json_decode('{"207":"test"}');
var_dump(key($x)); // string(3) "207"
var_dump($x);
// array(1) {
// ["207"]=>
// string(4) "test"
// }
$y['207'] = 'test';
var_dump(key($y)); // int(207)
var_dump($y);
// array(1) {
// [207]=>
// string(4) "test"
// }
print_r on both those arrays gives identical output, but with var_dump you can see the differences.
Here is some code that reproduces your exact problem:
$output = (array)json_decode('{"207":"sdf","210":"sdf"}');
print_r($output);
echo $output[207];
echo $output["207"];
And the simple fix is to pass in true to json_decode for the optional assoc argument, to specify that you want an array not an object:
$output = json_decode('{"207":"sdf","210":"sdf"}', true);
print_r($output);
echo $output[207];
echo $output["207"];
The problem arises when casting to array an object that has string keys that are valid integers.
If you have this object:
object(stdClass)#1 (2) {
["207"]=>
string(3) "sdf"
["210"]=>
string(3) "sdf"
}
and you cast it with
$array = (array)$object
you get this array
array(2) {
["207"]=>
string(3) "sdf"
["210"]=>
string(3) "sdf"
}
which has keys that can only be accessed by looping through them, since a direct access like $array["207"] will always be converted to $array[207], which does not exist.
Since you are getting an object like the one above from json_decode() applied to a string like
$json = '{"207":"sdf", "210":"sdf"}'
The best solution would be to avoid numeric keys in the first place. These are probably better modelled as numeric properties of an array of objects:
$json = '[{"numAttr":207, "strAttr":"sdf"}, {"numAttr":210, "strAttr":"sdf"}]'
This data structure has several advantages over the present one:
it better reflects the original data, as a collection of objects
which have a numeric property
it is readily extensible with other properties
it is more portable across different systems
(as you see, your current data structure is causing issues in PHP, but if you
should happen to use another language you may easily encounter
similar issues).
If a property → object map is needed, it can be quickly obtained, e.g., like this:
function getNumAttr($obj) { return $obj->numAttr; } // for backward compatibility
$arr = json_decode($json); // where $json = '[{"numAttr":...
$map = array_combine(array_map('getNumAttr', $arr), $arr);
The other solution would be to do as ascii-lime suggested: force json_decode() to output associative arrays instead of objects, by setting its second parameter to true:
$map = json_decode($json, true);
For your input data this produces directly
array(2) {
[207]=>
string(3) "sdf"
[210]=>
string(3) "sdf"
}
Note that the keys of the array are now integers instead of strings.
I would consider changing the JSON data structure a much cleaner solution, though, although I understand that it might not be possible to do so.
I've just found this bug which causes array elements to be inaccessible sometimes in PHP when the array is created by a call to unserialize.
Create a test PHP file containing (or run from the command line) the following script:
<?php
$a = unserialize('a:2:{s:2:"10";i:1;s:2:"01";i:2;}');
print $a['10']."\n";
$a['10'] = 3;
$a['01'] = 4;
print_r($a);
foreach ($a as $k => $v)
{
print 'KEY: ';
var_dump($k);
print 'VAL: ';
var_dump($v);
print "\n";
}
If you get errors you have a version of PHP with this bug in it and I recommend upgrading to PHP 5.3
Try
var_dump($output);
foreach ($output as $key => val) {
var_dump($key);
var_dump($val);
}
to learn more on what is happening.
What exact line/statement is throwing you a warning?
How did you print the array? I would suggest print_r($arrayName);
Next, you can print individual elements like: echo $arrayName[0];
Try use my approach:
class ObjectToArray {
public static function convert( $object ) {
if( !is_object( $object ) && !is_array( $object ) ) {
return $object;
}
if( is_object( $object ) ) {
$object = get_object_vars( $object );
}
return array_map( 'ObjectToArray::convert', $object );
}
}
$aNewArray = ObjectToArray::convert($oYourObject);
Just put error_reporting(0); in you method or at start of file. It will solved your issue.

Categories