I have this object:
$myobject = (object) [
'name' => [],
'value' => [],
'id' => [],
];
I want to add some values in a for each loop, but array push does not seem to work.
I've tried this:
$object_name = $myobject->name;
array_push($object_name, "testName");
I've looked everywhere but can't seem to find the answer.
You cann't use array_push this way. $object_name is not your main object.
When you push to $object_name, your $myobject is still empty.
You can fix it adding reference &, for example:
$object_name = &$myobject->name;
or just push to your original object:
array_push($myobject->name, "testName");
or
$myobject->name[] = "something";
Simple option is to add another item to the property using normal array notation.
e.g.
$object->name[] = 'testName';
Try this:
$names = ['A', 'B', 'C']; /* This is an array of names */
foreach ($names as $name) {
$myobject->name[] = $name;
}
echo '<pre>';
print_r($myobject);
Related
I'm struggling to find a way to convert my object to the correct format.
I want to replace a function that we currently use on generating detailed array, as you can see below everything is static.
private function departmentArray($content=[])
{
return [ static::$A_DEPT_ID => $content
, static::$O_DEPT_ID => $content
];
}
A sample result when that runs is this
{"3":{"complete":0,"incomplete":0},"5":{"complete":0,"incomplete":0}}
I converted the method
private function departmentArray($content=[])
{
$depts = d::getAllMainDepartment();
$dept_array = [];
foreach ($depts as $dept) {
$dept_array[] = array($dept->id => $content);
}
return $dept_array;
}
The resulting format looks like this
[{"3":{"complete":0,"incomplete":0}},{"5":{"complete":0,"incomplete":0}}]
How can I maintain the same format on the first version of code?
You don't push into an associative array, you use the new key as an index.
$dept_array[$dept->id] = $content;
I'm trying to add random numbers with array_push to an array in the field 'notes' => [] but I think I'm not doing it right since I do not see the random numbers stored in the array.
I am doing it in the following way:
$person1= [
'name' => 'person1',
'note' => []
];
$person2= [
'name' => 'person2',
'note' => []
];
$person3= [
'name' => 'person3',
'note' => []
];
$data=[$person1, $person2, $person3];
$_SESSION['data'] = $data;
function insertNumRandom(){
$data = $_SESSION['data'];
foreach ( $data as $student ) {
array_push($student['note'], rand(0,10));
}
}
function showNotes(){
foreach ( $data as $student ) {
echo implode($student['note']);
}
}
showNotes(); // To show the notes but it shows nothing.
You should change insertNumRandom like as below
function insertNumRandom(){
$data = $_SESSION['data'];
foreach ( $data as &$student ) {
array_push($student['note'], rand(0,10));
}
$_SESSION['data'] = $data;
}
showNotes function
function showNotes(){
$data = $_SESSION['data'];
foreach ( $data as $student ) {
echo implode($student['note']);
}
}
and call insertNumRandom before showNotes.
insertNumRandom();
showNotes();
You're referencing the $data with the "as" keyword which creates a new object.
You should instead iterate through the object you already have.
function insertNumRandom(){
$index = 0;
for($index = 0; $index<sizeof($data['data']); $index++ ) {
array_push($data[$index]['note'], rand(0,10));
}
}
try this maybe, still not sure how you're calling the insertNumRandom() function
function showNotes($arr){
foreach ( $arr as $student ) {
var_dump(implode($student['note']));
}
}
insertNumRandom();
showNotes($data);
you have a number of issues in your example.
First of all, the way you are using the $_SESSION object to pass some values to the function is not necessary, and not clean. You can either use global $data inside of the functions and they will suddenly have access to the $data variable from the parent scope. But even that is not very clean. I would suggest that you pass the data object by reference to the functions. That will make your function more portable and testable.
Your example is accessing the $student variable by value. All you need to do is to access it by reference by using the ampersand (&) in the foreach() like this foreach ( $data as &$student ) { ... }
I have noticed that you have never made a single call to insertNumRandom()
To have a better idea about what's in the arrays, I would suggest that you use a field separator for the implode() function and that you print a new line after imploding the array. I bet you will like the result.
Finally, just a word of advice ... array_push() lets you push one or more items in an array. But I personally use it only when I need to push multiple items in an array. For push just item new items, I use the short-hand $myArray[] = "new item";
So in practice, here is what your example will become ...
<?php
// Since you are not reusing $person1, $person2 and $person3 beyond the initialization
// phase, then let's keep things cleaner.
$data[] = [
'name' => 'person1',
'note' => []
];
$data[] = [
'name' => 'person2',
'note' => []
];
$data[] = [
'name' => 'person3',
'note' => []
];
/**
* In this function signature, the & means that the argument is passed by reference.
* That make it possible for the function to change the value of the argument.
*/
function insertNumRandom(&$theData) {
// The foreach() also needs to use $student by reference so that we can modify it
// by adding the random number to it.
foreach($theData as &$student) {
$student['note'][] = rand(0,10);
}
}
/**
* No need to pass $theData by reference because the function will not change its value.
*/
function showNotes($theData) {
// Here, the foreach() is using student by value because we do not need to change it's value.
foreach($theData as $student) {
echo implode($student['note'], ', ') . "\n";
}
}
// Inserting some random notes 3 times.
insertNumRandom($data);
insertNumRandom($data);
insertNumRandom($data);
showNotes($data); // To show the notes but it shows nothing.
?>
I want to make a foreach loop like this one
foreach ($this->data['array'] as $this->data['key'] => $this->data['value'])
{
echo $this->data['value'];
}
Yet the $this->data['value'] is never created. Why is this and what am I doing wrong?
In my understanding, you have a class in which there is a variable or array name $data.
Now, you added an array in $data with an index named 'array', right?
If so, this code will work properly -
class myClass{
public $data = array(); //$data is an array
function print_array(){
foreach ($this->data['array'] as $this->data['key'] => $this->data['value'])
{
echo $this->data['value'];
}
}
}
$ob = new myClass(); // object declaration for your class
array_push($ob->data,'array'); // added a value to the $data array.
$ob->data['array'] = array(); // the newly added value is declared as an index of an array
// Now simply push values to the array named $data['array']
array_push($ob->data['array'],1);
array_push($ob->data['array'],2);
array_push($ob->data['array'],3);
$ob->print_array(); // call the print_array() function. $this will be passed to that function
Hope this will help to understand.
If you still have problem, please comment.
To have a clear understanding, you can visit this link. There are lots of simple and interesting examples explained!
Happy Coding!
I think $this is for current class object reference not for an array
foreach ($this->data['array'] as $k => $v)
{
echo $v;
$this->data['key'][] = $k;
$this->data['value'][] = $v;
}
print_r($this->data['key']);
print_r($this->data['value']);
If:
class YourClass {
private data = array(
'array' => array(
'key1' => 'val1',
'key2' => 'val2', etc.
)
);
then it should be:
foreach ($this->data['array'] as $key => $val)
{
echo $val;
// if you want to add keys and vals to data array:
$this->data[$key] = $val;
}
All my AJAX requests are in json format which are being parsed in javascript.
How can i prevent null values being displayed in an HTML page without needing to write an if-statement in javascript for each json value?
Or should i write a custom PHP function to encode an array to json instead of using json_encode() so it doesn't display 'null' ?
In server side with PHP,
You can use array_filter before json_encode.
array_filter without second argument removes null elements of entry array, example :
$object= array(
0 => 'foo',
1 => false,
2 => -1,
3 => null,
4 => ''
);
$object = (object) array_filter((array) $object);
$result = json_encode($object);
The $result contains:
{"0":"foo","2":-1}
As you see, the null elements are removed.
I'm going to add to the accepted answer because that will only work if you have a 1 dimensional object or array. If there is any array or object nesting then in order to get the accepted solution to work, you must create some sort of recursive array filter. Not ideal.
The best solution my colleague and I came up with was to actually perform a regular expression on the JSON string before it was returned from the server.
$json = json_encode($complexObject);
echo preg_replace('/,\s*"[^"]+":null|"[^"]+":null,?/', '', $json);
The regular expression will remove all places in the string of the form ,"key":null including any whitespace between the leading comma and the start of the key. It will also match "key":null, afterwards to make sure that no null values were found at the beginning of a JSON object.
This isn't an ideal solution but it's far better than creating a recursive array filter given an object could be several dimensions deep. A better solution would be if json_encode had a flag that let you specify if you wanted null entries to remain in the output string.
To remove only NULL, but keep FALSE, '', and 0:
function is_not_null($var)
{
return !is_null($var);
}
echo json_encode(array_filter((array) $object, 'is_not_null'));
public function __toString() {
$obj = clone $this;
$keys = get_object_vars($obj);
foreach ($keys as $key => $value) {
if (!$value) {
unset($obj->{$key});
}
}
return json_encode($obj);
}
What about using the native JSON.stringify method on the javascript side?
You can set, a second parameter, a function to remove keys with a null value.
If you return undefined, the property is not included in the output JSON string (check the documentation for "the replacer parameter" at https://developer.mozilla.org/en-US/docs/Using_native_JSON#The_replacer_parameter).
function removeNulls(obj) {
var str = JSON.stringify(obj, function(key, val) {
if (val == null) return undefined;
return val;
});
return JSON.parse(str);
}
Then you can have a "normalized" JSON object by calling:
var obj = removeNulls(obj);
echo json_encode(array_filter((array) $object, function($val) {
return !empty($val);
}));
class Foo implements JsonSerializable
{
public $param1;
public $param2;
public function jsonSerialize()
{
return array_filter((array) $this, function ($var) {
return !is_null($var);
});
}
}
public function testJsonSerialization()
{
$expectedJson = '{"param1":true}';
$foo = new Foo();
$foo->param1 = true;
$foo->param2 = null;
$this->assertEquals(
$expectedJson,
json_encode($foo)
);
}`
of course you can create Abstract class with custom jsonSerialize method and extend all your DTOs from this
A version that works with multi-dimensional arrays.
$withoutNull = function($a) use (&$withoutNull) {
return array_filter(
array_map(
fn($p) => is_array($p) ? $withoutNull($p) : $p, $a
)
);
};
Example:
$a = [
"name" => "nathan",
"data" => [
"age" => 27,
"something" => null
],
"another" => null
];
$b = $withoutNull($a);
print_r($b);
Output:
Array
(
[name] => nathan
[data] => Array
(
[age] => 27
)
)
So I've got a class that I'd like to have it just set defaults if they're not passed in. For example, I can pass it an array called $options.
function new_score($options)
{
}
Then I'd like to have a different function that I can set a var to a default if a key with that var's name doesn't exist in the $options array;
The function definition could look like this:
function _set(&$key, $options, $default)
{
}
I know there's array_key_exists(), and I guess I'm sort of looking for a way to access the variables name.
For example:
$apple = 'orange';
How can I get the string 'apple', so I can look for that key? I know I could take the function _set() and have it look for $key, $var, $options, and $default, but I'd rather abstract it further.
function method($options)
{
//First, set an array of defaults:
$defaults = array( "something" => "default value",
"something_else" => "another default");
//Second, merge the defaults with the $options received:
$options = array_merge($defaults, $options);
//Now you have an array with the received values or defaults if value not received.
echo($options["something"]);
//If you wish, you can import variables into local scope with "extract()"
//but it's better not to do this...
extract($options);
echo($something);
}
References:
http://ar.php.net/manual/en/function.array-merge.php
http://ar.php.net/manual/en/function.extract.php
there's two ways of doing this:
One at a time with the ternary operator:
$key = isset($array['foo']) ? $array['foo'] : 'default';
Or, as an array as a whole:
$defaults = array('foo' => 'bar', 'other' => 'default value');
$array = $array + $defaults;
How about this:
class Configurable
{
private static $defaults = array (
'propertyOne'=>'defaultOne',
'propertyTwo'=>'defaultTwo'
);
private $options;
public function __construct ($options)
{
$this->options = array_merge (self::$defaults, $options);
}
}
From the documentation for array_merge:
If the input arrays have the same
string keys, then the later value for
that key will overwrite the previous
one.