I have a function called createCost, and inside that function, I have an array_map that takes in an array and a function called checkDescription that's inside that createCost. Below is an example:
public function createCost{
$cost_example = array();
function checkDescription($array_item)
{
return $array_item;
}
$array_mapped = array_map('checkDescription', $cost_example);
}
When I run this I get a
array_map() expects parameter 1 to be a valid callback, function 'checkDescription' not found or invalid function name
Which to my understanding is that it looked for the function checkDescription outside that createCost but how can I call checkDescription from inside?
Do like this
public function createCost(){
$cost_example = array();
$array_mapped = array_map(function ($array_item){
return $array_item;
}, $cost_example);
}
Why not assign the function to a variable?
public function createCost{
$cost_example = array();
$checkDescription = function ($array_item) {
return $array_item;
}
$array_mapped = array_map($checkDescription, $cost_example);
}
Isn't this more readable too?
Related
I would like overwrite array element returned as reference. I can do it like this:
$tmp = $this->event_users_details;
$tmp = &$tmp->firstValue("surcharge");
$tmp += $debt_amount;
I would do it in one line like:
$this->event_users_details->firstValue("surcharge") += $debt_amount;
but I get Can't use method return value in write context
Where $this->event_users_details is a object injected in constructor.
My function look like:
public function & firstValue(string $property) {
return $this->first()->{$property};
}
public function first() : EventUserDetails {
return reset($this->users);
}
and users is a private array.
You can't do it without temporary variable stores "surcharge" value.
From documentation:
To return a reference from a function, use the reference operator & in both the function declaration and when assigning the returned value to a variable:
<?php
function &returns_reference()
{
return $someref;
}
$newref =& returns_reference();
?>
I checked it with this code:
class Item
{
public $foo = 0;
}
class Container
{
private $arr = [];
public function __construct()
{
$this->arr = [new Item()];
}
public function &firstValue($propNme)
{
return $this->first()->{$propNme};
}
private function first()
{
return reset($this->arr);
}
}
$container = new Container();
var_dump($value = &$container->firstValue('foo')); // 0
$value += 1;
var_dump($container->firstValue('foo')); // 1
I am building a PHP function to enqueue JavaScript files into a PHP array and then have another PHP function that will load all the JS files into a page and load them in the order based on a sort number that can be passed into the enqueue function. Similar to how WordPress loads JS and CSS files.
So my PHP function enqueue_js_script() might look like this below which takes in a key name for the JS file, a file path to the JS file, and a sort order number which is optional. It then would add the JS file to a PHP class property $this->_js_files[$script_key]...
public function enqueue_js_script($script_key, $file_source, $load_order = 0){
$this->_js_scripts[$script_key] = $file_source;
}
Then I will also have a PHP function load_js_scripts() which will print each script file path into the header of a webpages HTML.
This is where I want to take into consideration the $load_order passed into enqueue_js_script() to print the scripts into the HTML in the order based on these numbers.
How can I use this sort order number to sort my array of JS scripts?
UPDATE
It looks like I should store the sort number in an array like this instead...
$this->_js_files[$script_key] = array(
'file_source' => $file_source,
'sort' => $load_order
);
Using usort and a custom sorting function:
<?php
public function enqueue_js_script($script_key, $file_source, $load_order = 0){
$jsScript = new \stdClass;
$jsScript->load_order = $load_order;
$jsScript->script_key = $script_key;
$this->_js_scripts[$script_key] = $jsScript;
}
function sortJSFiles($a, $b)
{
if ($a->load_order == $b->load_order) {
return 0;
}
return ($a->load_order < $b->load_order) ? -1 : 1;
}
usort($this->_js_scripts, "sortJSFiles");
Having to pass your array key is not really good practice. The $array[] = $foo construction adds $foo as the new last item of $array.
Using usort.
<?php
class OrderStack {
private $contents = array();
public function add($order, $load) {
if (!is_int($order) || $order < 0) {
throw new InvalidArgumentException("$order must be a non-negative integer");
}
$this->contents[] = array($order, $load);
}
public function get_array() {
usort(
$this->contents,
'OrderStack::compare'
);
return array_map(
'OrderStack::get_load',
$this->contents
);
}
private static function get_load($stack_item) {
return $stack_item[1];
}
private static function compare($a, $b) {
return $a[0] - $b[0];
}
}
class YourClass {
private $_js_scripts;
public function __construct() {
$this->_js_scripts = new OrderStack();
}
public function enqueue_js_script($file_source, $load_order = 0) {
$this->_js_scripts->add($load_order, $file_source);
}
public function get_js_scripts() {
return $this->_js_scripts->get_array();
}
}
?>
The OrderStack class is reusable.
class Test
{
public $data = array();
public function addData($data = array())
{
array_merge($data, $this->data);
return $this;
}
public function showData()
{
print_r($this->data);
}
}
$test = new Test;
$test->addData(array("halo", "zaki"))->showData();
i tried to merging 2 array, but it doesn't work, maybe someone can explain to me?
array_merge does not modify the arrays passed to it, but rather returns the result.
Try this:
public function addData($data = array())
{
$this->data = array_merge($data, $this->data);
return $this;
}
You forgot to assign the resulting array to member variable $data. It should be,
$this->data = array_merge($data, $this->data);
I use __remap() function to avoid any undefine method and make it redirect to index() function.
function __remap($method)
{
$array = {"method1","method2"};
in_array($method,$array) ? $this->$method() : $this->index();
}
That function will check if other than method1 and method2.. it will redirect to index function.
Now, how I can automatically grab all public function methods in that controller instead of manually put on $array variable?
You need to test if method exists and is public. So you need use reflection and method exists. Something like this:
function __remap($method)
{
if(method_exists($this, $method)){
$reflection = new ReflectionMethod($this, $method);
if($reflection->isPublic()){
return $this->{$method}();
}
}
return $this->index();
}
Or you can use get_class_methods() for create your array of methods
OK, I was bored:
$r = new ReflectionClass(__CLASS__);
$methods = array_map(function($v) {
return $v->name;
},
$r->getMethods(ReflectionMethod::IS_PUBLIC));
I've modified the codes and become like this.
function _remap($method)
{
$controllers = new ReflectionClass(__CLASS__);
$obj_method_existed = array_map(function($method_existed)
{
return $method_existed;
},
$controllers->getMethods(ReflectionMethod::IS_PUBLIC));
$arr_method = array();
//The following FOREACH I think was not good practice.
foreach($obj_method_existed as $method_existed):
$arr_method[] = $method_existed->name;
endforeach;
in_array($method, $arr_method) ? $this->$method() : $this->index();
}
Any enhancement instead of using foreach?
I have two functions and Im trying to pass an array of data to the function that have the view like this:
function one()
{
$data['array'] = $array;
$this->load->view('etc/asdf', $data);
}
function two()
{
$array[];
return $array;
}
What Im doing wrong?
Thank you in Advance!
Try:
$data['array'] = $this->two(); // Instead of $array, as it is undefined
$this->load->view('etc/asdf', $data);
And also to define array you have to do following $array = array();, not $array[];
Note: You have to invoke function rather than specify $array, as it is returned from function called two
function one()
{
$data['array'] = $this->two();
$this->load->view('etc/asdf', $data);
}
function two()
{
$array= array('1','2','2');
return $array;
}
instead of $data['array'] = two();
use $data['array'] = $this->two();