Can't seem to make this work.
I want to make the array below available to a second function but it always comes up empty
The main code is this:
function GenerateSitemap($params = array()) {
$array = extract(shortcode_atts(array(
'title' => 'Site map',
'id' => 'sitemap',
'depth' => 2
), $params));
global $array;
}
function secondfunction()
{
global $array;
print $title;
// this function throws an error and can't access the $title key from the first function
}
GenerateSitemap()
secondfunction()
I'd like to use the title, id or depth KEYS inside a second function. They just come up empty and throw an error
"The scope of a variable is the context within which it is defined."
http://us3.php.net/language.variables.scope.php
You need to define the variable (at least initially) outside the function:
$array = array();
function GenerateSitemap($params = array()) {
global $array;
$array = extract(shortcode_atts(array(
'title' => 'Site map',
'id' => 'sitemap',
'depth' => 2
), $params));
}
function SecondFunction() {
global $array;
...
}
You need to declare the variable as global before you use it inside the function, otherwise it will implicitly create a local variable.
function myFunc() {
global $myVar;
$myVar = 'Hello World';
}
myFunc();
print_r($myVar); // 'Hello World'
You don't actually have to declare it initially in the globalscope, you will not get a notice/warning/error, although it is obviously good practice to do so. (Although if good practice is the goal then you probably shouldn't be using global variables to begin with.)
Related
Both of the two techniques below seem to work okay. I would just like to know which technique is the most proper technique.
// parameters
$text_str = 'antique picture';
$error_arr = array();
The $error_arr variable is included in the parameters:
function step_one($text_str,$error_arr) {
global $error_arr;
//... some code goes here ...
$error_arr['step_one'] = true;
}
function step_two($text_str,$error_arr) {
global $error_arr;
//... some code goes here ...
$error_arr['step_two'] = true;
}
// call the two functions that have $error_arr included in the parameters
step_one($test_str,$error_arr);
step_two($text_str,$error_arr);
// they output the following
print_r outputs array('step_one' => 1)
print_r outputs array('step_one' => 1, 'step_two' => 1)
The $error_arr variable is omitted from the parameters.
function step_one($text_str) {
global $error_arr;
//... some code goes here ...
$error_arr['step_one'] = true;
}
function step_two($text_str) {
global $error_arr;
//... some code goes here ...
$error_arr['step_two'] = true;
}
// call the functions that have the $error_arr variable omitted from the parameters
step_one($text_str);
step_two($text_str);
// the last two functions have exactly the same output as the
// first two functions even though the `$error_arr` is not included
// in the parameters
print_r outputs array('step_one' => 1)
print_r outputs array('step_one' => 1, 'step_two' => 1)
I am running PHP 7.1 on a shared hosting. I have got display_errors turned on in the control panel.
PHP does not throw any error messages if I include the $error_arr variable in the parameters or if I use the functions that omit the $error_arr variable from the parameters.
You can have something like:
$error_arr = [
'step_one' => step_one($text_str),
'step_two' => step_two($text_str),
];
It is not clear from the question what is the purpose of this code, so some approaches or other may be better. For example if you need to process $text_str in several steps just in this particular place - you can use closures instead:
$processing = [
'step_one' => function($str) { /* some code */ return true },
'step_two' => function($str) { /* some code */ return true },
];
$results = [];
foreach($processing as $func) {
array_push($results, $func($text_str));
}
If you want these functions to share some variable - you can pass it through use clause:
$shared = [];
$processing = [
'step_one' => function($str) use ($shared) { /* some code */ return true },
'step_two' => function($str) use ($shared) { /* some code */ return true },
];
$results = [];
foreach($processing as $func) {
array_push($results, $func($text_str));
}
The two techniques are actually the same technique.
Here's an example:
$error_arr = ['example' => 'value'];
$not_error_arr = ['something' => 'else'];
function step_one($text_str, $error_arr) {
global $error_arr;
$error_arr['step_one'] = true;
}
step_one('foo', $not_error_arr);
var_dump($error_arr, $not_error_arr);
This will output
array (size=2)
'example' => string 'value' (length=5) 'step_one' => boolean true
array (size=1)
'something' => string 'else' (length=4)
The 'step_one' value is not assigned to the array you passed as a parameter, because that assignment has been overriden by the global $error_arr.
So, regardless of what you pass as the second argument to
function step_one($text_str,$error_arr) {...
the global definition within the function means it will be ignored. It only looks like you're writing to it because the variable in global scope happens to be the same one you passed as a parameter.
How to correctly write default value for assocc array function argument?
function foo($arr['key']='value');
<?php
function foo($arr = null)
{
if (is_null($arr))
{
$arr = array(
'key' => 'value'
);
}
...
You cant use the direct way you tried above. Just work with this little workaround
Else you might go with this:
function foo($a = array('key' => 'value'))
{
...
But in my opinion its a bit unhandy to declare an array in the function head. Its purely on you how you want to use it
there's a problem, I can not understand what I'm doing wrong ..
I want to get the value of the function of the other features in WordPress ..
This code replaces some parts of the code ..
I want to get the value of the argument variable words (it needs to go $attr['words']) and then use the other functions (new_quote).
<?php
/*
* Plugin Name: Random Quotes
*/
function random_quote($atts) {
extract( shortcode_atts( array(
'path' => plugin_dir_path(__FILE__).'quotes.txt',// default, if not set
'label_new' => 'New Quote',
'words' => 'no' // yes or no
), $atts ) );
$temp = $attr['words']; // no
...
}
add_shortcode('randomquotes','random_quote');
function new_quote(){
global $temp; // NULL
/*
global $attr;
$temp = $attr['words']; // again NULL
*/
...
if($temp == "no") {
...
}
}
...
?>
What am I doing wrong? Maybe just can not get the value of this variable?
It looks like you need to declare global $temp within your random_quote() function. Right now, random_quote() is using a local version of $temp, which is lost when the function is completed.
EDIT: Here's an example snippet
<?php
function test() {
global $temp;
$temp = 'no';
}
function my_test() {
global $temp;
var_dump($temp);
}
test();
my_test();
?>
I can't seem to find anything of this, and was wondering if it's possible to store a function or function reference as a value for an array element. For e.g.
array("someFunc" => &x(), "anotherFunc" => $this->anotherFunc())
Thanks!
You can "reference" any function. A function reference is not a reference in the sense of "address in memory" or something. It's merely the name of the function.
<?php
$functions = array(
'regular' => 'strlen',
'class_function' => array('ClassName', 'functionName'),
'object_method' => array($object, 'methodName'),
'closure' => function($foo) {
return $foo;
},
);
// while this works
$functions['regular']();
// this doesn't
$functions['class_function']();
// to make this work across the board, you'll need either
call_user_func($functions['object_method'], $arg1, $arg2, $arg3);
// or
call_user_func_array($functions['object_method'], array($arg1, $arg2, $arg3));
PHP supports the concept of variable functions, so you can do something like this:
function foo() { echo "bar"; }
$array = array('fun' => 'foo');
$array['fun']();
Yout can check more examples in manual.
Yes, you can:
$array = array(
'func' => function($var) { return $var * 2; },
);
var_dump($array['func'](2));
This does, of course, require PHP anonymous function support, which arrived with PHP version 5.3.0. This is going to leave you with quite unreadable code though.
check out PHP's call_user_func. consider the below example.
consider two functions
function a($param)
{
return $param;
}
function b($param)
{
return $param;
}
$array = array('a' => 'first function param', 'b' => 'second function param');
now if you want to execute all the function in a sequence you can do it with a loop.
foreach($array as $functionName => $param) {
call_user_func($functioName, $param);
}
plus array can hold any data type, be it function call, nested arrays, object, string, integer etc. etc.
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.