PHP: Collect all variables passed to a function as array? - php

I was thinking about the possibility of accessing all the variables that are passed into an function, and merge them into an array. (Without passing variables into an array from the beginning)
Pseudo-code:
// Call function
newFunction('one', 'two', 'three' ) ;// All values are interpreted as a one rray in some way
// Function layout
newFunction( ) {
// $functionvariables = array( All passed variables)
foreach ($functionvariable as $k => $v) {
// Do stuff
}
}

http://php.net/func_get_args

Take a look at func_get_args function. This is how you can build an array for them:
function test()
{
$numargs = func_num_args();
$arg_list = func_get_args();
$args = array();
for ($i = 0; $i < $numargs; $i++)
{
$args[] = $arg_list[$i];
}
print_r($args);
}

It can be useful to clearly identify that the items you are passing in should be treated as an array. For instance, set your function def to
function newFunction( $arrayOfArguments ) {
foreach($arrayOfArguments as $argKey => $argVal)
{ /* blah */ }
}

Related

PHP: How to pass array as argument to receiving function that uses func_get_args?

I'm having a problem with getting an array (with all its data) over to a receiving function. I am passing the array over as a constructor argument ($myarray):
$s = new MyQuery($param1, $myarray);
The receiving side is a MyQuery object receiving the arguments, using:
$a = func_get_args();
But it does not give me the values in the array:
If I do:
$size=func_num_args();
$a=func_get_args();
for ($i=0;$i<$size;$i++) {
if (is_array($a[$i])){
$arr = $a[$i]; //trying to get the very array....
echo ($arr[0]);
}
}
.. the echo here does just say "Array". Does it have to do with the func_get_args() function?
Very thankful for any help.
Try this code:
<?php
function foo()
{
$argsCount = func_num_args();
$args=func_get_args();
for ($i = 0; $i < $argsCount ; $i++) {
if (is_array($args[$i])){
print_r($args[$i]);
}
}
}
foo(1, 2, [3]);
?>
output
Array
(
[0] => 3
)
Actually you should be able to get you array with this piece of code
But echo can't print the full array.
Try replacing echo ($arr[0]); by var_dump($arr); or print_r($arr);

PHP Array of Methods and Parameters

I'm passing an array of methods and parameters to my object. The array can be any size with any number of methods and/or parameters. In between the methods are the parameters.
EDIT: Sorry that this was not clear. The parameters following a method are for THAT method. So in the first example below method1 has two parameters (param1 and param2), method2 has two parameters (param1 and param2) and method3 has one parameter (param).
Here are some examples:
array = ["method1","param1","param2","method2","param1","param2","method3","param"];
array = ["method1","param1","param2","method2","param"];
array = ["method","param"];
I can pull the methods from the array using method_exists but I'm trying to pull the parameters from the array. This is what I've got so far:
// Loop thru $array to find methods
$methods = array();
for($i=0; $i < count($array); $i++) {
if(method_exists($this,$array[$i]) === TRUE) {
$methods[] = $i;
}
}
// Get parameters for methods
// If there is only one method take the remaining array values
// else get the parameters in between the methods
if(count($methods) == 1) {
$parameters = array_slice($array,1,count($array));
} else {
??
}
How can I grab the array values for parameters that match up to the methods when the array values for methods are variable?
You are close, but I believe you only want to process the array once. Remember - all of your array values are either "methods" OR "parameters". Therefore, if you are able to find "methods", you can also find "parameters".
$methods = array();
$parameters = array();
$curParameters = null;
for($i=0; $i < count($array); $i++) {
if(method_exists($this,$array[$i]) === TRUE) {
//associate last set of paremeters with method
if ($curParameters != null) {
$parameters[] = $curParameters;
}
//new method, new curParams
$methods[] = $i;
$curParameters = array();
} else {
//$array[$i] must be a parameter for the last method found
$curParameters[] = $array[$i];
}
}
//need to save the last set params founds
$parametres[] = $curParameters
When this is done parsing, you should have two arrays. The first array is $methods and the second is $parameters. These arrays should match up 1 to 1, meaning $parameters[x] should match up with $methods[x].
You could just turn
for($i=0; $i < count($array); $i++) {
if(method_exists($this,$array[$i]) === TRUE) {
$methods[] = $i;
}
}
To
$j = 0;
for($i=0; $i < count($array); $i++) {
if(method_exists($this,$array[$i]) === TRUE) {
$methods[] = $i;
$j++;
}
else {
$parameters[$j][] = $array[$i];
}
}
What you could do here is check if the value you are pulling out is in your methods array. If it is, then you know it is a method and not a parameter. if it isn't then you know it to be a parameter.
I would use the array_search() php method to accomplish this.
so you code would look something like:
for($x=0;$x<count($array);$x++)
{
if( array_search($array[$x], $methods) !== false)
{
//This is a Parameter
}
}
You can find more information here: http://php.net/manual/en/function.array-search.php
As I understand the question, you have an array of methods and parameters, and you want to separate these - presumably into separate arrays.
If so, you can try the following simplified example:
<?php
// example object with some public methods...
class Foo
{
function method1() {}
function method2() {}
function method3() {}
}
// list of methods and params
$array = [
'method1',
'param1',
'param2',
'method2',
'param3',
'method3',
'param4',
'param5',
];
// get a list of Foo's methods
$methods = get_class_methods('Foo');
// array_diff to get the params only
$params = array_diff($array, $methods);
print_r($params);
Yields:
Array
(
[1] => param1
[2] => param2
[4] => param3
[6] => param4
[7] => param5
)
YMMV - this example is outside the context of the object, so get_class_methods() can only see public methods. It can be used inside an object to get protected and private methods too. It depends on your exact use case.
Hope this helps.
It is more efficient to build $parameters array when building $methods array. But if for some unkown reasons, you want to keep your code as is, here is a way to do it:
$methods = array();
for($i=0; $i < count($array); $i++) {
if(method_exists($this,$array[$i]) === TRUE) {
$methods[] = $i;
}
}
if(count($methods) == 1) {
$parameters = array_slice($array,1,count($array));
} else {
$parameters = array();
for ($k=0; $k < (count($methods) - 1); $k++)
$parameters[$k] = array_slice($array,$methods[$k]+1,$methods[$k+1]-$methods[$k]-1);
$parameters[$k] = array_slice($array,$methods[$k]+1,count($methods)-$methods[$k]-1);
}
print_r($parameters);

Transform array to key-value array without iteration

What is the easiest way to map array of objects to key-value array of objects, where key is some property of an object?
For example:
class Cartoon
{
public $title;
public function __construct($title)
{
$this->title = $title;
}
}
$cartoons = array(new Cartoon('Tom and Jerry'), new Cartoon('Cheburashka'));
$mappedCartoons = array();
foreach ($cartoons as $cartoon)
{
$mappedCartoons[$cartoon->title] = $cartoon;
}
print_r ($mappedCartoons);
PS. I wonder if iteration and the extra variable $mappedCartoons can be disposed of?
You could use array_reduce to achive your goal.
<?php
$cartoons = array_reduce($cartoons, function($result, $cartoon) {
$result[$cartoon->title] = $cartoon;
return $result;
}, array());
?>
the idea is not mine, found here: http://www.danielauener.com/howto-use-array_map-functionality-on-an-associative-array-changing-keys-and-values/
If you must use basic arrays you can simply type out the keys when creating them:
$cartoons = array(
'Tom and Jerry' => new Cartoon('Tom and Jerry'),
'Cheburashka' => new Cartoon('Cheburashka'),
);
Alternatively you can create container object that implements various array/iteration related interfaces and can be used as a regular array:
class CartoonArray extends ArrayObject {
public function __construct($input, $flags = 0, $iterator_class = "ArrayIterator") {
parent::__construct(array(), $flags, $iterator_class);
// since the original ArrayObject implemented in C and they don't it won't pick up our overriden ossetSet we have to type it out here explicitly
foreach ($input as $value) {
$this->offsetSet(null, $value);
}
}
public function offsetSet($index, $value) {
parent::offsetSet($value->title, $value);
}
}
$cartoons = new CartoonArray(array(new Cartoon('Tom and Jerry'), new Cartoon('Cheburashka')));
$cartoons[] = new Cartoon('Sesame street');
print $cartoons['Tom and Jerry']->title;
unset($cartoons['Tom and Jerry']);
foreach ($cartoons as $k => $v) {
print $k."\n";
}
I can't think of a way that doesn't involve iterating. I can think of a way of not needing an additional variable though:
$cartoons = array(new Cartoon('Tom and Jerry'), new Cartoon('Cheburashka'));
foreach( $cartoons as $key => $cartoon )
{
$cartoons[ $cartoon->title ] = $cartoon;
unset( $cartoons[ $key ] );
}
var_dump( $cartoons );
However, the documentation of foreach notes:
As foreach relies on the internal array pointer changing it within the loop may lead to unexpected behavior.
I'm not entirely sure that this applies to my example as well. Maybe someone else can chime in here.
To be safe, perhaps this alternative is more appropriate, as it initiates $len with the initial length of $cartoons, before iteration:
$cartoons = array(new Cartoon('Tom and Jerry'), new Cartoon('Cheburashka'));
for( $i = 0, $len = count( $cartoons ); $i < $len; $i++ )
{
$cartoon = $cartoons[ $i ];
$cartoons[ $cartoon->title ] = $cartoon;
unset( $cartoons[ $i ] );
}
var_dump( $cartoons );
This example assumes the initial $cartoons has 'proper' sequentially numbered keys, starting at 0, though.

Most efficient way to search for object in an array by a specific property's value

What would be the fastest, most efficient way to implement a search method that will return an object with a qualifying id?
Sample object array:
$array = [
(object) ['id' => 'one', 'color' => 'white'],
(object) ['id' => 'two', 'color' => 'red'],
(object) ['id' => 'three', 'color' => 'blue']
];
What do I write inside of:
function findObjectById($id){
}
The desired result would return the object at $array[0] if I called:
$obj = findObjectById('one')
Otherwise, it would return false if I passed 'four' as the parameter.
You can iterate that objects:
function findObjectById($id){
$array = array( /* your array of objects */ );
foreach ( $array as $element ) {
if ( $id == $element->id ) {
return $element;
}
}
return false;
}
Edit:
Faster way is to have an array with keys equals to objects' ids (if unique);
Then you can build your function as follow:
function findObjectById($id){
$array = array( /* your array of objects with ids as keys */ );
if ( isset( $array[$id] ) ) {
return $array[$id];
}
return false;
}
It's an old question but for the canonical reference as it was missing in the pure form:
$obj = array_column($array, null, 'id')['one'] ?? false;
The false is per the questions requirement to return false. It represents the non-matching value, e.g. you can make it null for example as an alternative suggestion.
This works transparently since PHP 7.0. In case you (still) have an older version, there are user-space implementations of it that can be used as a drop-in replacement.
However array_column also means to copy a whole array. This might not be wanted.
Instead it could be used to index the array and then map over with array_flip:
$index = array_column($array, 'id');
$map = array_flip($index);
$obj = $array[$map['one'] ?? null] ?? false;
On the index the search problem might still be the same, the map just offers the index in the original array so there is a reference system.
Keep in mind thought that this might not be necessary as PHP has copy-on-write. So there might be less duplication as intentionally thought. So this is to show some options.
Another option is to go through the whole array and unless the object is already found, check for a match. One way to do this is with array_reduce:
$obj = array_reduce($array, static function ($carry, $item) {
return $carry === false && $item->id === 'one' ? $item : $carry;
}, false);
This variant again is with the returning false requirement for no-match.
It is a bit more straight forward with null:
$obj = array_reduce($array, static function ($carry, $item) {
return $carry ?? ($item->id === 'one' ? $item : $carry);
}, null);
And a different no-match requirement can then be added with $obj = ...) ?? false; for example.
Fully exposing to foreach within a function of its own even has the benefit to directly exit on match:
$result = null;
foreach ($array as $object) {
if ($object->id === 'one') {
$result = $object;
break;
}
}
unset($object);
$obj = $result ?? false;
This is effectively the original answer by hsz, which shows how universally it can be applied.
You can use the function array_search of php like this
$key=array_search("one", array_column(json_decode(json_encode($array),TRUE), 'color'));
var_dump($array[$key]);
i: is the index of item in array
1: is the property value looking for
$arr: Array looking inside
'ID': the property key
$i = array_search(1, array_column($arr, 'ID'));
$element = ($i !== false ? $arr[$i] : null);
Well, you would would have to loop through them and check compare the ID's unless your array is sorted (by ID) in which case you can implement a searching algorithm like binary search or something of that sort to make it quicker.
My suggestion would be to first sort the arrays using a sorting algorithm (binary sort, insertion sort or quick sort) if the array is not sorted already. Then you can implement a search algorithm which should improve performance and I think that's as good as it gets.
http://www.algolist.net/Algorithms/Binary_search
This is my absolute favorite algorithm for very quickly finding what I need in a very large array, quickly. It is a Binary Search Algorithm implementation I created and use extensively in my PHP code. It hands-down beats straight-forward iterative search routines. You can vary it a multitude of ways to fit your need, but the basic algorithm remains the same.
To use it (this variation), the array must be sorted, by the index you want to find, in lowest-to-highest order.
function quick_find(&$array, $property, $value_to_find, &$first_index) {
$l = 0;
$r = count($array) - 1;
$m = 0;
while ($l <= $r) {
$m = floor(($l + $r) / 2);
if ($array[$m]->{$property} < $value_to_find) {
$l = $m + 1;
} else if ($array[$m]->{$property} > $value_to_find) {
$r = $m - 1;
} else {
$first_index = $m;
return $array[$m];
}
}
return FALSE;
}
And to test it out:
/* Define a class to put into our array of objects */
class test_object {
public $index;
public $whatever_you_want;
public function __construct( $index_to_assign ) {
$this->index = $index_to_assign;
$this->whatever_you_want = rand(1, 10000000);
}
}
/* Initialize an empty array we will fill with our objects */
$my_array = array();
/* Get a random starting index to simulate data (possibly loaded from a database) */
$my_index = rand(1256, 30000);
/* Say we are needing to locate the record with this index */
$index_to_locate = $my_index + rand(200, 30234);
/*
* Fill "$my_array()" with ONE MILLION objects of type "test_object"
*
* 1,000,000 objects may take a little bit to generate. If you don't
* feel patient, you may lower the number!
*
*/
for ($i = 0; $i < 1000000; $i++) {
$searchable_object = new test_object($my_index); // Create the object
array_push($my_array, $searchable_object); // Add it to the "$my_array" array
$my_index++; /* Increment our unique index */
}
echo "Searching array of ".count($my_array)." objects for index: " . $index_to_locate ."\n\n";
$index_found = -1; // Variable into which the array-index at which our object was found will be placed upon return of the function.
$object = quick_find($my_array, "index", $index_to_locate, $index_found);
if ($object == NULL) {
echo "Index $index_to_locate was not contained in the array.\n";
} else {
echo "Object found at index $index_found!\n";
print_r($object);
}
echo "\n\n";
Now, a few notes:
You MAY use this to find non-unique indexes; the array MUST still be sorted in ascending order. Then, when it finds an element matching your criteria, you must walk the array backwards to find the first element, or forward to find the last. It will add a few "hops" to your search, but it will still most likely be faster than iterating a large array.
For STRING indexes, you can change the arithmetic comparisons (i.e. " > " and " < " ) in quick_find() to PHP's function "strcasecmp()". Just make sure the STRING indexes are sorted the same way (for the example implementation): Alphabetically and Ascending.
And if you want to have a version that can search arrays of objects sorted in EITHER ascending OR decending order:
function quick_find_a(&$array, $property, $value_to_find, &$first_index) {
$l = 0;
$r = count($array) - 1;
$m = 0;
while ($l <= $r) {
$m = floor(($l + $r) / 2);
if ($array[$m]->{$property} < $value_to_find) {
$l = $m + 1;
} else if ($array[$m]->{$property} > $value_to_find) {
$r = $m - 1;
} else {
$first_index = $m;
return $array[$m];
}
}
return FALSE;
}
function quick_find_d(&$array, $property, $value_to_find, &$first_index) {
$l = 0;
$r = count($array) - 1;
$m = 0;
while ($l <= $r) {
$m = floor(($l + $r) / 2);
if ($value_to_find > $array[$m]->{$property}) {
$r = $m - 1;
} else if ($value_to_find < $array[$m]->{$property}) {
$l = $m + 1;
} else {
$first_index = $m;
return $array[$m];
}
}
return FALSE;
}
function quick_find(&$array, $property, $value_to_find, &$first_index) {
if ($array[0]->{$property} < $array[count($array)-1]->{$property}) {
return quick_find_a($array, $property, $value_to_find, $first_index);
} else {
return quick_find_d($array, $property, $value_to_find, $first_index);
}
}
The thing with performance of data structures is not only how to get but mostly how to store my data.
If you are free to design your array, use an associative array:
$array['one']->id = 'one';
$array['one']->color = 'white';
$array['two']->id = 'two';
$array['two']->color = 'red';
$array['three']->id = 'three';
$array['three']->color = 'blue';
Finding is then the most cheap: $one = $array['one];
UPDATE:
If you cannot modify your array constitution, you could create a separate array which maps ids to indexes. Finding an object this way does not cost any time:
$map['one'] = 0;
$map['two'] = 1;
$map['three'] = 2;
...
getObjectById() then first lookups the index of the id within the original array and secondly returns the right object:
$index = $map[$id];
return $array[$index];
Something I like to do in these situations is to create a referential array, thus avoiding having to re-copy the object but having the power to use the reference to it like the object itself.
$array['one']->id = 'one';
$array['one']->color = 'white';
$array['two']->id = 'two';
$array['two']->color = 'red';
$array['three']->id = 'three';
$array['three']->color = 'blue';
Then we can create a simple referential array:
$ref = array();
foreach ( $array as $row )
$ref[$row->id] = &$array[$row->id];
Now we can simply test if an instance exists in the array and even use it like the original object if we wanted:
if ( isset( $ref['one'] ) )
echo $ref['one']->color;
would output:
white
If the id in question did not exist, the isset() would return false, so there's no need to iterate the original object over and over looking for a value...we just use PHP's isset() function and avoid using a separate function altogether.
Please note when using references that you want use the "&" with the original array and not the iterator, so using &$row would not give you what you want.
This is definitely not efficient, O(N). But it looks sexy:
$result = array_reduce($array, function ($found, $obj) use ($id) {
return $obj['id'] == $id ? $obj : $found;
}, null);
addendum:
I see hakre already posted something akin to this.
Here is what I use. Reusable functions that loop through an array of objects. The second one allows you to retrieve a single object directly out of all matches (the first one to match criteria).
function get_objects_where($match, $objects) {
if ($match == '' || !is_array($match)) return array ();
$wanted_objects = array ();
foreach ($objects as $object) {
$wanted = false;
foreach ($match as $k => $v) {
if (is_object($object) && isset($object->$k) && $object->$k == $v) {
$wanted = true;
} else {
$wanted = false;
break;
};
};
if ($wanted) $wanted_objects[] = $object;
};
return $wanted_objects;
};
function get_object_where($match, $objects) {
if ($match == '' || !is_array($match)) return (object) array ();
$wanted_objects = get_objects_where($match, $objects);
return count($wanted_objects) > 0 ? $wanted_objects[0] : (object) array ();
};
The easiest way:
function objectToArray($obj) {
return json_decode(json_encode($obj), true);
}

How to dynamically set array keys in php

I have some logic that is being used to sort data but depending on the user input the data is grouped differently. Right now I have five different functions that contain the same logic but different groupings. Is there a way to combine these functions and dynamically set a value that will group properly. Within the function these assignments are happening
For example, sometimes I store the calculations simply by:
$calcs[$meter['UnitType']['name']] = ...
but other times need a more specific grouping:
$calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] =...
As you can see sometimes it is stored in a multidiminesional array and other times not. I have been trying to use eval() but without success (not sure that is the correct approach). Storing the data in a temporary variable does not really save much because there are many nested loops and if statements so the array would have to be repeated in multiple places.
EDIT
I hope the following example explains my problem better. It is obviously a dumbed down version:
if(){
$calcs[$meter['UnitType']['name']] = $data;
} else {
while () {
$calcs[$meter['UnitType']['name']] = $data;
}
}
Now the same logic can be used but for storing it in different keys:
if(){
$calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data;
} else {
while () {
$calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data;
}
}
Is there a way to abstract out the keys in the $calc[] array so that I can have one function instead of having multiple functions with different array keys?
You can use this if you want to get&set array values dynamically.
function getVal($data,$chain){
$level = $data;
for($i=0;$i<count($chain);$i++){
if(isset($level[$chain[$i]]))
$level = $level[$chain[$i]];
else
return null; // key does not exist, return null
}
return $level;
}
function setVal(&$data,$chain,$value){
$level = &$data;
for($i=0;$i<count($chain);$i++){
$level = &$level[$chain[$i]]; // set reference (&) in order to change the value of the object
}
$level = $value;
}
How it works:
Calling getVal($data,array('foo','bar','2017-08')) will return the equivalent of $data['foo']['bar']['2017-08'].
Calling setVal($data,array('foo','bar','2017-08'),'hello') will set value as if you called
$data['foo']['bar']['2017-08'] = 'hello'. non-existent keys will be created automatically by php magic.
This can be useful if you want to build the structure of the array dynamically.
Here's a function I wrote for setting deeply nested members on arrays or objects:
function dict_set($var, $path, $val) {
if(empty($var))
$var = is_array($var) ? array() : new stdClass();
$parts = explode('.', $path);
$ptr =& $var;
if(is_array($parts))
foreach($parts as $part) {
if('[]' == $part) {
if(is_array($ptr))
$ptr =& $ptr[];
} elseif(is_array($ptr)) {
if(!isset($ptr[$part]))
$ptr[$part] = array();
$ptr =& $ptr[$part];
} elseif(is_object($ptr)) {
if(!isset($ptr->$part))
$ptr->$part = array();
$ptr =& $ptr->$part;
}
}
$ptr = $val;
return $var;
}
Using your example data:
$array = [];
$array = dict_set($array, 'resource1.unit1.2017-10', 'value1');
$array = dict_set($array, 'resource1.unit2.2017-11', 'value2');
$array = dict_set($array, 'resource2.unit1.2017-10', 'value3');
print_r($array);
Results in output like:
Array
(
[resource1] => Array
(
[unit1] => Array
(
[2017-10] => value1
)
[unit2] => Array
(
[2017-11] => value2
)
)
[resource2] => Array
(
[unit1] => Array
(
[2017-10] => value3
)
)
)
The second argument to dict_set() is a $path string in dot-notation. You can build this using dynamic keys with period delimiters between the parts. The function works with arrays and objects.
It can also append incremental members to deeply nested array by using [] as an element of the $path. For instance: parent.child.child.[]
Would it not be easier to do the following
$calcs = array(
$meter['Resource']['name'] => array(
$meter['UnitType']['name'] => 'Some Value',
$meter['UnitType']['name2'] => 'Some Value Again'
),
);
or you can use Objects
$calcs = new stdClass();
$calcs->{$meter['UnitType']['name']} = 'Some Value';
but I would advice you build your structure in arrays and then do!
$calcs = (object)$calcs_array;
or you can loop your first array into a new array!
$new = array();
$d = date('Y-m',$start);
foreach($meter as $key => $value)
{
$new[$key]['name'][$d] = array();
}
Give it ago and see how the array structure comes out.
Try to use a switch case.
<?php
$userinput = $calcs[$meter['UnitType']['name']] = $data;;
switch ($userinput) {
case "useriput1":
while () {
$calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data;
}
break;
case "userinput2":
while () {
$calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data;
}
break;
...
default:
while () {
$calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data;
}
}
?>
I agree with the comment on the OP by #Jake N that perhaps using objects is a better approach. Nonetheless, if you want to use arrays, you can check for the existence of keys in a conditional, like so:
if(
array_key_exists('Resource', $meter)
) {
$calcs[$meter['Resource']['name']][$meter['UnitType']['name']][date('Y-m',$start)] = $data;
} else {
$calcs[$meter['UnitType']['name']] = $data;
}
On the other hand, if you want to use objects, you can create a MeterReading object type, and then add MeterReading instances as array elements to your $calcs array, like so:
// Object defintion
class MeterReading {
private $data;
private $resource;
private $startDate;
private $unitType;
public function __construct(Array $meter, $start, $data) {
$this->unitType = $meter['UnitType']['name'];
$this->resource = $meter['Resource']['name'];
$this->startDate = date('Y-m',$start);
}
public function data() {
return $this->data;
}
public function resource() {
return $this->resource;
}
public function startDate() {
return $this->startDate;
}
public function unitType() {
return $this->unitType;
}
}
// Example population
$calcs[] = new MeterReading($meter, $start, $data);
// Example usage
foreach($calcs as $calc) {
if($calc->resource()) {
echo 'Resource: ' . $calc->resource() . '<br>';
}
echo 'Unit Type: ' . $calc->unitType() . '<br>';
echo 'Start Date: ' . $calc->startDate() . '<br>';
echo 'Data: ' . $calc->data() . '<br>';
}
Obviously you can take this further, such as checking the existence of array keys in the object constructor, giving the object property resource a default value if not provided, and so on, but this is a start to an OO approach.
You can use this library to get or set value in multidimensional array using array of keys:
Arr::getNestedElement($calcs, [
$meter['Resource']['name'],
$meter['UnitType']['name'],
date('Y-m', $start)
]);
to get value or:
Arr::handleNestedElement($calcs, [
$meter['Resource']['name'],
$meter['UnitType']['name'],
date('Y-m', $start)
], $data);
to set $data as value.

Categories