PHP Using code as a function, variables not working - php

I've got this code which works well standalone:
file_put_contents('dataFile', implode('',
array_map(function($data) {
return stristr($data,"NSQ = ") ? "NSQ = school\n" : $data;
}, file('dateFile'))
));
This reads dataFile and finds the entry NSQ = and updates it to be NSQ = school
I'm going to reuse this multple times so changed it into a function:
function updatesite($site) {
file_put_contents('dataFile', implode('',
array_map(function($data) {
return stristr($data,"$site = ") ? "$site = school\n" : $data;
}, file('dateFile'))
));
}
Initially, I got an error that $site didn't exist, so I added global $site; before the return.
That stopped the error, but it doesn't update the file.
Is there any way I can use a variable like this?

You can use use to pass variables to a function callback like this:
function updatesite($site) {
file_put_contents('dataFile', implode('',
array_map(function($data) use ($site) {
return stristr($data,"$site = ") ? "$site = school\n" : $data;
}, file('dateFile'))
));
}

Related

How to call a function with other function as argument

im just learning php
Im trying to add a log with comments to my functions output.
Right now it looks like this:
//the function
function add1($x){
if($GLOBALS['logging'] === 'on'){ $log[] = 'Adding 1 to '.$x;};
$a = $x + 1;
if($GLOBALS['logging'] === 'on'){
$return[] = $a;
$return[] = $log;
return $return;
}else{ return $a; };
};
//calling the function
if($GLOBALS['logging'] === 'on'){
$return = add1($x);
$number = $return[0];
$log = $return[1];
}else{ $number = add1($x); };
Im kinda annoyed by the fact i need to retype this if statement.
So i made a seperate function for returning the function
which looks like this:
//function
function log_return($data = 'x', $log = 'x'){
if($GLOBALS['logging'] === 'on'){
if($data !== 'x') $return[] = $data;
if($log !== 'x') $return[] = $log;
return $return;
} return $data;
};//function end
And returning it with:
return $return = isset($log) ? log_return($data, $log) : log_return($data);
Now my quastion is: Is there a way to call a function with function..
like:
call_function(add1($x));
so i can return it either with log or without..
Given the answer https://stackoverflow.com/a/2700760/5387193 - this should work:
function add1($a)
{
// add1 code goes here
}
function call_function($name, $param)
{
$name($param);
}
call_function('add1', $x);
On a side note, your variable and function names aren't very intuitive. Perhaps you should study how to write good quality readable code. I recommend reading chapter 9 of Refactoring by Martin Fowler, it's quite good. You can find a PDF version on the web.
Another note, your return statement return $return = isset($log) ? log_return($data, $log) : log_return($data); has a unnecessary assignment to $return. The code should simply read
return isset($log) ? log_return($data, $log) : log_return($data);
Yes, it is possible. To simplify:
function first($x) {
return $x+1;
}
function second($y) {
return $y+1;
}
echo second(first(1)); // Returns 3, ie. 1+1+1
As gview said in his comment, don't use global variables. Argument lists exist for several reasons, included but not limited to making code easier to read, edit, and debug. The same goes for function and variable names.
Moreover, your code is very messy. It can be consolidated:
function addTo($currentValue, $valueToAdd, $logging = 0)
{
if ($logging) {
logWrite('addTo', "Adding $valueToAdd to $currentValue");
return $currentValue + $valueToAdd;
} else {
return $currentValue;
}
}
function logWrite($operation, $message)
{
$log = getLog(); // maybe it's a file, or DB record or something
// perform the write, depending on your implementation
}
$number = addTo($someStaringValue, $someOtherValue, 1);
All of this said, logging should not control program flow. In other words, whether something is logged by the system or not should have no bearing on what your code is trying to do. I really think you need to take a broader view of what you're trying to do and break it up into components.
At best, your code should tell a logger to log info, and the logger itself should determine if logging is actually turned on. If it is, the info is logged. If not, then the code that calls on the logger still works and goes about its business.

How Can we pass function parameter as another function which itself has different parameters?

I have function below :
function cache_activity_data($cid,$somefunction) {
$cache_time = '+15 minutes';
$cache_id = $cid;
$expire = strtotime($cache_time);
$cache = cache_get($cache_id);
if (!empty($cache->data)) {
if (time() > $cache->expire) {
cache_clear_all($cache_id, 'cache_custom_activity_dashboard');
$report = $somefunction; // will get from function
cache_set($cache_id, $report, 'cache_custom_activity_dashboard', $expire);
}
else {
$report = $cache->data;
}
}
else {
$report = $somefunction; // will get from function
cache_set($cache_id, $report, 'cache_custom_activity_dashboard', $expire);
}
return $report;
}
Now $somefunction can be like below examples :
total_comments_per_user($user->uid);
total_comments_per_user_time_limit($user->uid, $user_year_start);
total_revisions_time_limit($month_ago);
total_revisions_time_limit($year_start);
every time I need to pass like 20 different functions. Is that possible I am getting error as at place of varibales I am passing function But I am not able to figure is that possible.
How I want to use :
//want to write this as function
$cache_revisions_total = cache_get("total_revisions", "cache_custom_activity_dashboard");
if (!empty($cache_revisions_total->data)) {
if (time() > $cache_revisions_total->expire) {
cache_clear_all("total_revisions", 'cache_custom_activity_dashboard');
$t_revisions = total_revisions();
cache_set("total_revisions", $t_revisions, 'cache_custom_activity_dashboard', $expire);
}
else {
$t_revisions = $cache_revisions_total->data;
}
}
else {
$t_revisions = total_revisions();
cache_set("total_revisions", $t_revisions, 'cache_custom_activity_dashboard', $expire);
}
// want to write this as function end here
$vars['total_bubbla_rev'] = number_format(($t_revisions / $days_from_rev_start), 2, '.', '');
// here i want to do same so i need to write function or should i repeat code
$y_revisions = total_revisions_time_limit($year_start);
$vars['yearly_bubbla_rev'] = number_format(($y_revisions / $year_days), 2, '.', '');
// here i want to do same so i need to write function or should i repeat code
$m_revisions = total_revisions_time_limit($month_ago);
$vars['monthly_bubbla_rev'] = number_format(($m_revisions / 30), 2, '.', '');
Please suggest, Thanks!
I see two possible options.
Option 1
You could use Anonymous functions. I simplified your function but you'll get the idea:
function cache_activity_data($cid, $somefunction) {
$report = $somefunction();
}
Define your functions as anonymous functions:
$parm1 = "banana";
$parm2 = "fruit";
$your_function1 = function() use ($parm1, $parm2) {
echo "$parm1 is a $parm2";
};
$your_function2 = function() use ($parm1) {
echo $parm1;
};
Usage:
cache_activity_data($cid, $your_function1); // shows "banana is a fruit"
cache_activity_data($cid, $your_function2); // shows "banana"
Read carefully through the documentation. Especially the part about variable scopes.
Option 2
Another possibility is call_user_func_array() but this requires you to make a little adjustment to cache_activity_data(). You need to add a third parameter which holds an array:
function cache_activity_data($cid, $somefunction, $somefunction_parms) {
$report = call_user_func_array($somefunction, $somefunction_parms);
}
Define your functions as usual:
function your_function1($parm1, $parm2) {
echo "$parm1 is a $parm2";
}
function your_function2($parm) {
echo $parm;
}
Usage
cache_activity_data($cid, "your_function1", array("banana", "fruit")); // shows "banana is a fruit"
cache_activity_data($cid, "your_function2", array("banana")); // shows "banana"
First, you cannot pass functions as parameters, however you can use callbacks as explained here:
http://php.net/manual/en/language.types.callable.php
But in your case, this seems irrelevant as you are not determining the function or changing its value in cache_activity_data().
Therefore, you might want to do like this:
$reportDefault = total_comments_per_user($user->uid);
// Or ... $reportDefault = total_revisions_time_limit, total_comments_per_user_time_limit, etc..
$report = cache_activity_data($cid, $reportDefault);
You do not need to add pass $report or any function as parameter.

Laravel : I want to return the result of chunk function , to get it in the view with Ajax

I want to return the result of chunk. The problem is , when I iterate with foreach, I put echo result it displays the result but when I want to return it , I have a blank page
$tab = array();
Product::blabla ->chunk (500, function($results))
{
foreach($results as $result)
{
array_push ($tab,$result);
echo $results;// works
return $results;// doesn't return anything
}
}
return $tab; // to be sent to Ajax type get
Closure can be stored into variable, so just add to variable.
$tab = Product::blabla()->chunk (500, function($results))
{
// your logic
return $results;
};
return $tab
This is not working actually, it just return true. You have to make the closure function use an external variable by reference example:
$output = [];
$tab = Product::blabla()->chunk (500, function($results) use (&$output))
{
$output = array_combine($output, $results);
};
return $output;

How to exclude a variable from being required in a function?

How to exclude a variable from being required in a function?
IE:
function foo($name,$address,$pizza_preference,$date)
{
if(!$pizza_preference)
{
return array($name,$address,$date);
}
else
{
return array($name,$address,$pizza_preference,$date);
}
}
When calling this function how would I set it up so $pizza_preference is not required, but optional? So that if you only entered 3 arguments in the function it omits $pizza_preference, or would I have to make it so when you enter 0 it just doesn't return it?
Just define a default value for it. Then you can use that function without passing a value:
function foo($name,$address,$date,$pizza_preference=null)
{
if(!$pizza_preference)
{
return array($name,$address,$date);
}
else
{
return array($name,$address,$pizza_preference,$date);
}
}
Usually you put variables that have default values at the end of the parameters list so you don't have to include blank parameters when calling the function.
See Default argument values on the PHP website for more.
UPDATE
If you're going to have multiple parameters with default values and want to be able to skip them individually you can pass an array as the only parameter and read the values from there:
function foo(array $parameters)
{
if(!$parameters['pizza_preference'])
{
return array($parameters['name'],$parameters['address'],$parameters['date']);
}
else
{
return array($parameters['name'],$parameters['address'],$parameters['date'],$parameters['pizza_preference']);
}
}
I recommend (and I always do) to pass arguments as Object..
function foo($params)
{
if(!$params->pizza_preference)
{
return array($pizza_preference->name,$pizza_preference->address,$pizza_preference->date);
}
else
{
return array($pizza_preference->name,$pizza_preference->pizza_preference->address,$pizza_preference,$pizza_preference->date);
}
}
Sample usage:
$p1 = new stdClass;
$p1->name = 'same name';
$p1->address ='same address';
$p1->pizza_preference = '1';
$p1->date = '26-04-2012';
$p2 = new stdClass;
$p2->name = 'same name';
$p2->address ='same address';
$p2->date = '26-04-2012';
foo($p1); //will return the first array
foo($p2); //will return the second array
Well youll need to change the signature... anything not required should go last:
function foo($name, $address, $date, $pizza_preference = null) {
}
You can set default values in the function declaration:
function foo($name,$address,$date,$pizza_preference=null)
{
if($pizza_preference === null)
{
return array($name,$address,$date);
}
else
{
return array($name,$address,$pizza_preference,$date);
}
}
As an alternative approach, you can use an associative array as a single argument, and then just check it inside the function like this:
function foo($args) {
$name = (!empty($args['name']) ? $args['name'] : NULL);
$address = (!empty($args['address']) ? $args['address'] : NULL);
$pizza_preference = (!empty($args['pizza_preference']) ? $args['pizza_preference'] : NULL);
$date = (!empty($args['date']) ? $args['date'] : NULL);
}

Issue with array_map callback

At first I had this (work in wamp but not in my web server)
$ids = array_map(function($item) { return $item['user_id']; }, $data['student_teacher']);`
So I try to convert the code to that but nothing work ( i got Array,Array,Array,Array,Array,Array from outpout )
$ids = array_map($this->myarraymap(null), $data['student_teacher']);
function myarraymap($item) {
return $item['user_id'];
}
You need to pass it a callback, and not actually pass it the execution of the function, i.e.,
$ids = array_map(array($this, 'myarraymap'), $data['student_teacher']);
function myarraymap($item) {
return $item['user_id'];
}

Categories