php extract() associative array when a function is called - php

I have this function:
function extractAvailable($assoc1, $assoc2){
if($assoc1) extract($assoc1);
else extract($assoc2);
}
What I expect is to call this function later in the global scope, and have my variables available, like so:
$arr1 = [];
$arr2 = ['one'=>1, 'two'=>'SecondItem'];
extractAvailable($arr1, $arr2);
With the call on extractAvailable(), I need to have the varialbes $one and $two available in the current scope. Obviously, I've got something wrongly figured concerning variable scope use here, 'cause it isn't working. When I try to use the variable, what I get instead is Notice: Undefined variable: one.
How do I get this to work?

You could add the new data to the $GLOBALS array which would have the effect of making them available in other scopes.
function extractAvailable($assoc1, $assoc2){
if($assoc1) {
foreach ($assoc1 as $key => $value) {
$GLOBALS[$key] = $value;
}
} else {
foreach ($assoc2 as $key => $value) {
$GLOBALS[$key] = $value;
}
}
}
But I have to wonder why you need to extract anything from a perfectly good array and place the exact same data into scalar variables.
All this does is double your memory requirement for no benefit whatsoever

If you want them to be available in the global scope, you can use variable variables instead of extract, and specify them as global.
function extractAvailable($assoc1, $assoc2){
if($assoc1) {
foreach ($assoc1 as $key => $value) {
global $$key;
$$key = $value;
}
} else {
foreach ($assoc2 as $key => $value) {
global $$key;
$$key = $value;
}
}
}

Related

Can't access global array outside of an if statement?

I am having some issues with setting a global array in php. The data I get from $_POST is straight from my database. I sent it through an external page to JSON decode/etc. (that part works, so I didnt paste the code). I only want to do this if data is set, then I want to take that array and do other things with it throughout the rest of my code. The problem I am having is the array outside of the if statement is null. I can't seem to figure out why? If I were to echo a var_dump inside the if statement, the values are inside the GLOBALS['Array']
function is_assoc($array) {
foreach (array_keys($array) as $k => $v) {
if ($k !== $v)
return true;
}
return false;
}
$GLOBALS['Array'] = array();
if (isset($_POST['data'])) {
$Data = $_POST['data'];
$decode = new JSONdecoder($Data);
$decode->decodeNew($Data);
$Data = $decode->decodedArray;
$decryptor = new DataDecryptor(base64_decode($_POST['key']), $_POST['tracking'], $hostName);
$decodedData = $decryptor->decrypt_arr($Data);
foreach($decodedData as $key => $val){
if(is_assoc($val)){
foreach($val as $key2 => $val2){
$theArray[$key2] = $val2;
}
}else{
$theArray[$key] = $val;
}
}
$GLOBALS['Array'] = $theArray;
}
echo var_Dump($Array);
Your issue is somewhere else. $GLOBALS is a superglobal variable accessible from any scope.
When you define a new entry in $GLOBALS, it automatically creates a variable holding the same name, but that variable is only visible in that particular scope. If you are in another scope and you want to initialize that as a variable, you need to use the global keyword : global $var; (look at the code below for an example - inside the test() function).
Are you sure 100% that you are always doing the same tests (Are you 100% positive that when testing, you are always entering the foreach statement?)
To clarify the behavior of $GLOBALS:
<?php
$GLOBALS['foo'] = 'bar';
var_dump($foo); // outputs 'bar'
if (true) {
$GLOBALS['foo'] = 'bar2';
}
var_dump($foo); // outputs 'bar2'
function test() {
var_dump($foo); // notice undefined variable - outputs NULL
var_dump($GLOBALS['foo']); // outputs 'bar2'
global $foo;
var_dump($foo); // outputs 'bar2';
}
test();

PHP reference variable by case-insensitive string

PHP 5. I'm in a situation where I need to translate a case-insensitive url query to member variables in a PHP object. Basically, I need to know what member variable the url query key points to so I can know if it's numeric or not.
For example:
class Foo{
$Str;
$Num;
}
myurl.com/stuff?$var=value&num=1
When processing this URL query, I need to know that "str" associates with Foo->$Str, etc. Any ideas on how to approach this? I can't come up with anything.
Try something like this.
function fooHasProperty($foo, $name) {
$name = strtolower($name);
foreach ($foo as $prop => $val) {
if (strtolower($prop) == $name) {
return $prop;
}
}
return FALSE;
}
$foo = new Foo;
// Loop through all of the variables passed via the URL
foreach ($_GET as $index => $value) {
// Check if the object has a property matching the name of the variable passed in the URL
$prop = fooHasProperty($foo, $index);
// Object property exists already
if ($prop !== FALSE) {
$foo->{$prop} = $value;
}
}
And it may help to take a look at php's documentation on Classes and Objects.
Example:
URL: myurl.com/stuff?var=value&num=1
Then $_GET looks like this:
array('var' => 'value', 'num' => '1')
Looping through that, we would be checking if $foo has a property var, ($foo->var) and if it has a property num ($foo->num).

how to Extract variables without using extract()?

I would like a function to export variables to the scope it's called within without using extract(), e.g.
function get_vars(){
$return['a'] = 1;
$return['b'] = 2
return $return;
}
and then rather than using :
exctract(get_vars());
I would just use
get_vars();
is there anyway available??
Saw that possible solution at the php manuel of the extract function.
(http://www.php.net/manual/en/function.extract.php#62727)
function free_args (&$V) {
foreach ($V as $k => &$v) {
$$k =& $v;
}
unset ($k); unset ($v); unset ($V);
// be careful that if you need to extract $k, $v or $V variables you should find other names for them in the lines above (ie. $__k, $__v and $__V)
}
You can try to use global keyword
function get_vars() {
global $a, $b;
$a = 1;
$b =2;
}
But as for me, it is a very weird approach. I prefer to use OOP.

Defining a function with name from a variable?

I need to create a column-system for Wordpress with shortcodes, which is not a problem, but I'm trying to make it with less code.
I have an array with the data needed, I loop through it, create a unique-named function and set it as shortcode-function. The third step is a mystery. How can I create a function from a variable.
Here's an example, how it should be done:
$data[] = "first";
$data[] = "second";
foreach($data as $key => $value) {
function $value($atts,$content) {
return '<div class="'.$value.'">'.$content.'</div>';
}
add_shortcode($value,$value);
}
However, it seems that it's not possible to make it work like that in PHP. Is there any way to make this work, as I would not want to write all the (identical) functions separated. I could make the shortcode something like [col first]text[/col] but the client wants to have different names for every one of them.
you can use the double dollar syntax to use the value of a variable as a variable identifier,
Example:
$variable = "test";
$$variable = "value of test"
echo $test; //or echo $$variable;
I have never tried but you way want to try:
foreach($data as $key => $value)
{
function $$value($atts,$content)
{
}
add_shortcode($value,$value);
}
or a function like create_function
if your using PHP 5.3 or greater then you can do something like so:
$$value = function()
{
}
which should work fine
I'm not sure how WP invocates the functions, but if it uses call_user_func then you might cheat by using an object with virtual methods:
class fake_functions {
function __call($name, $params) {
return '<div class="'.$name.'">'.$params[1].'</div>';
}
}
$obj = new fake_functions();
foreach ($data as $value) {
add_shortcode($value, array($obj,$value));
}

php: array_replace_recursive alternative

I need a solution for array_replace_recursive, because my php-version isn't high enough. I want to use this code:
$_GET = array_replace_recursive($_GET, array("__amp__"=>"&"));
easy, isn't it?
On the PHP docs page for array_replace_recursive, someone posted the following source code to use in place of it:
<?php
if (!function_exists('array_replace_recursive'))
{
function array_replace_recursive($array, $array1)
{
function recurse($array, $array1)
{
foreach ($array1 as $key => $value)
{
// create new key in $array, if it is empty or not an array
if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key])))
{
$array[$key] = array();
}
// overwrite the value in the base array
if (is_array($value))
{
$value = recurse($array[$key], $value);
}
$array[$key] = $value;
}
return $array;
}
// handle the arguments, merge one by one
$args = func_get_args();
$array = $args[0];
if (!is_array($array))
{
return $array;
}
for ($i = 1; $i < count($args); $i++)
{
if (is_array($args[$i]))
{
$array = recurse($array, $args[$i]);
}
}
return $array;
}
}
?>
The code above by #Justin is ok, save for 2 things:
Function is not readily available at start of php execution be cause it is wrapped in if(). PHP docu says
When a function is defined in a conditional manner such as the two examples shown. Its definition must be processed prior to being called.
Most importantly; calling the function twice results in fatal error.
PHP docu says
All functions and classes in PHP have the global scope - they can be called outside a function even if they were defined inside and vice versa.
So I just moved the recurse function outside array_replace_recursive function and it worked well. I also removed the if() condition and renamed it to array_replace_recursive_b4php53 for fear of future upgradings

Categories