how to use global multidimensional arrays in PHP? - php

I tries to use multidimensional global arrays in PHP. Unfortunately, so far I don't know how to do it...
global $datawords;
function unfold_sentence($str)
{
$sentence_arr = preg_split('/[.?!]/',$str);
$i=0;
foreach ($sentence_arr as $value) {
$i++;
$datawords['sentence'][$i]['sentence'] = $value;
$datawords['sentence'][$i]['words'] = preg_split( '/[-?!.,;: ]+/', $value);
}
}
unfold_sentence("hello! how are you?");
print_r($datawords['sentence'][1]['sentence']); //empty echo
I tried to use $GLOBALS - instead of $datawords - unsuccessfully.

global is a keyword that you would use in the function where you want to reference the global variable. The PHP documentation gives an example for using the global keyword, and states:
By declaring $a and $b global within the function, all references to either variable will refer to the global version.
Note that you can have $i generated by the foreach loop itself.
So it should be:
function unfold_sentence($str)
{
global $datawords;
$sentence_arr = preg_split('/[.?!]/',$str);
foreach ($sentence_arr as $i => $value) {
$datawords['sentence'][$i]['sentence'] = $value;
$datawords['sentence'][$i]['words'] = preg_split( '/[-?!.,;: ]+/', $value);
}
}

Related

array_push() function not working in recursive function

I am using a recursive function in php. The function travers through an array and inputs some values of the array in a new array. I am using array_push() to enter values in the new array and I have also tried to do it without using array_push. This is the part of the function that calls the recursive function
if ($this->input->post('id') != '') {
$id = $this->input->post('id');
global $array_ins;
$k=0;
$data['condition_array'] = $this->array_check($id, $menus['parents'], $k);
// trial
echo "<pre>";
print_r($menus['parents']);
print_r($data['condition_array']);die;
// trial
}
and this here is the recursive function
function array_check($val, $array_main, $k) {
// echo $val . "<br>";
$array_ins[$k] = $val;
echo $k . "<br>";
$k++;
// $array_ins = array_push($array_ins, $val);
echo "<pre>";
print_r($array_ins);
if ($array_main[$val] != '') {
for ($i = 0; $i < sizeof($array_main[$val]); $i++) {
$this->array_check($array_main[$val][$i], $array_main, $k);
}
// $k++;
}
I've been trying to fix this erorr for quite some time with no luck . I would really appreciate any help possible .
thanks in advance
Move the global $array_ins; statement into the function.
Pass the variable $array_ins as a parameter to function
function array_check($val, $array_main, $k,$array_ins) {
}
and call the function
$this->array_check($id, $menus['parents'], $k,$array_ins);
or
function array_check($val, $array_main, $k) {
global $array_ins;
}
usage of global is not recommended in php check it here Are global variables in PHP considered bad practice? If so, why?
The global keyword should be used inside of functions so that the variable will refer to the value in the outer scope.
<?php
$a = 1;
$b = 2;
function Sum()
{
global $a, $b;
$b = $a + $b;
}
Sum();
echo $b; // 3

How does extract() create variables in the current scope?

I'm curious, how does the PHP's function extract do it's work? I would like to make a slightly modified version. I want my function to make the variable names when extracting from the keys of the array from snake notation to camelCase e.g:
Now extract does this:
$array = ['foo_bar' => 'baz'];
extract($array);
// $foo_bar = 'baz';
What I would like is:
camelExtract($array);
// $fooBar = 'baz';
Now I could of course camelCase the array first, but it would be nice if this could be done in a single function.
edit:
It seems some people misread my question. Yes I could do this:
function camelExtract($array)
{
$array = ['foo_bar' => 'baz'];
$camelCased = [];
foreach($array as $key => $val)
{
$camelCased[camelcase($key)] = $val;
}
extract($camelCased);
// $fooBar = 'baz';
// I can't "return" the extracted variables here
// .. now $fooBar is only available in this scope
}
camelExtract($array);
// Not here
But as I've stated, then the $fooBar is only visible within that scope.
I guess I could do something as extract(camelCaseArray($array)); and that would work.
This should work:-
function camel(array $arr)
{
foreach($arr as $a => $b)
{
$a = lcfirst(str_replace(" ", "", ucwords(str_replace("_", " ", $a))));
$GLOBALS[$a] = $b;
}
}
You can (cautiously) use variable variables:
function camelExtract($vals = array()) {
foreach ($vals as $key => $v) {
$splitVar = explode('_', $key);
$first = true;
foreach ($splitVar as &$word) {
if (!$first) {
$word = ucfirst($word);
}
$first = false;
}
$key = implode('', $splitVar);
global ${$key};
${$key} = $v;
}
}
This has now been tested and functions as expected. This condensed answer (after it addressed the lowercase first word) also works great and is much more condensed - mine is just a little more of a "step by step" to work through how the camel is done.
extract, and modification to the callees local symbol table from within a called function is magic. There is no way to perform the equivalent in plain-PHP without using it.
The final task can be solved using John Conde's suggesting of using extra after performing a transformation to the supplied array keys; although my recommendation is to avoid extract-like behavior entirely. The approach would then look similar to
extract(camelcase_keys($arr));
where such code is not wrapped in a function so that extract is executed from the scope of the symbol table in which to import the variables.
This extract behavior is is unlike variable-variables (in a called function) and is unlike using $GLOBALS as it mutates the callees (and only the callees) symbol table as see seen in this demo:
function extract_container () {
extract(array("foo" => "bar"));
return $foo;
}
echo "Extract: " . extract_container() . "\n"; // "bar" =>
echo "Current: " . $foo . "\n"; // => {no $foo in scope}
echo "Global: " . $GLOBALS['foo'] . "\n"; // => {no 'foo' in GLOBALS}
The C implementation for extract can be found in ext/standard/array.c. This behavior is allowed because the native function does not create a new/local PHP symbol table for itself; as such it is allowed to (trivially) modify the symbol table of the calling PHP context.
<?php
$arr = array('foo_bar'=>'smth');
function camelExtract($arr) {
foreach($arr as $k=>$v) {
$newName = lcfirst(str_replace(" ","",ucwords(str_replace("_"," ",$k))));
global $$newName;
$$newName = $v;
//var_dump($newName,$$newName);
}
}
camelExtract($arr);
?>
or just like (t's what you suggest, and better to mimic the original extract)
$camelArray[lcfirst(str_replace(" ","",ucwords(str_replace("_"," ",$k))))] = $v;
and extract on the resulting camelArray

Function returns empty array

I'm attempting to pass the denominator variable to the function convert. When I do, the returned array "$new_arr" produces "0" for each value.
I have tried replacing the variable $denominator with a digit within the function and the new array returns with the appropriate numbers.
My experience with PHP is novice so my questions are:
1) Is this an issue of scoping? I thought by declaring these variables outside of the function, they were inherently global.
2) Do I need to pass '$denominator' as an argument as well?
Thanks in advance. Here's the code.
$highest_val = max($array_1);
$lowest_val = min($array_2);
$denominator = $highest_val - $lowest_val;
function convert($arr)
{
$new_arr=array();
for($i=0, $count = count($arr); $i<$count; $i++)
{
$numerator = $arr[$i]-$lowest_val;
$calc = $numerator/$denominator;
$new_arr[] .= $calc;
}
$arr = $new_arr;
return $arr;
}
$test_arr = convert($open_array);
var_dump($test_arr);
To use Global variables inside your function, you need to define them global there too. Like this
$highest_val = max($array_1);
$lowest_val = min($array_2);
$denominator = $highest_val - $lowest_val;
function convert($arr)
{
global $highest_val;
global $lowest_val ;
global $denominator;
Or you can simply send those three values as parameters to your function. You can also use $GLOBALS array if you follow the global scope path
Yes, you do need to pass in the values as parameters into the function.
function convert($arr, $highest_val, $lowest_val, $denominator) { ... }
$test_arr = convert($open_array, $highest_val, $lowest_val, $denominator);
var_dump($test_arr);

compact() variables into array by prefix?

Is this possible?
Like make an array with all the variables that have a certain prefix?
I don't need the keys just the values, but I guess I could use array_values on the array.
If you need to do this, it's probably not written very well to begin with, but, here's how to do it :)
$foobar = 'test';
$anothervar = 'anothertest';
$foooverflow = 'fo';
$barfoo = 'foobar';
$prefix = 'foo';
$output = array();
$vars = get_defined_vars();
foreach ($vars as $key => $value) {
if (strpos($key, $prefix) === 0) $output[] = $value;
}
/*
$output = array(
'test', // from $foobar
'fo', // from $foooverflow
);
*/
http://php.net/manual/en/function.get-defined-vars.php
my eyes are bleeding a little, but I couldn't resist a one liner.
print_r(iterator_to_array(new RegexIterator(new ArrayIterator(get_defined_vars()), '/^' . preg_quote($prefix) . '/', RegexIterator::GET_MATCH, RegexIterator::USE_KEY)));
If you're talking about variables in the global scope, you could do this with $GLOBALS[]:
$newarray = array();
// Iterate over all current global vars
foreach ($GLOBALS as $key => $value) {
// And add those with keys matching prefix_ to a new array
if (strpos($key, 'prefix_' === 0) {
$newarray[$key] = $value;
}
}
If you have lots and lots of variables in global scope, this is going to be slower in execution than manually adding them all to compact(), but faster to type out.
Addendum
I would just add (though I suspect you already know) that if you have the ability to refactor this code, you are better off to group the related variables together into an array in the first place.
This, my second answer, shows how to do this without making a mess of the global scope by using a simple PHP object:
$v = new stdClass();
$v->foo = "bar";
$v->scope = "your friend";
$v->using_classes = "a good idea";
$v->foo_overflow = "a bad day";
echo "Man, this is $v->using_classes!\n";
$prefix = "foo";
$output = array();
$refl = new ReflectionObject($v);
foreach ($refl->getProperties() as $prop) {
if (strpos($prop->getName(), $prefix) === 0) $output[] = $prop->getValue($v);
}
var_export($output);
Here's the output:
Man, this is a good idea!
array (
0 => 'bar',
1 => 'a bad day',
)

PHP Foreach array as a error in function (invalid argument for foreach in...)

Im working on a new minimal Project, but i've got an error, i dont know why.
Normally, i use arrays after i first created them with $array = array();
but in this case i create it without this code, heres an example full code, which outputs the error:
<?php $i = array('demo', 'demo'); $array['demo/demodemo'] = $i; ?>
<?php $i = array('demo', 'demo'); $array['demo/demodemo2'] = $i; ?>
<?php
foreach($array as $a)
{
echo $a[0] . '<br>';
}
function echo_array_demo() {
foreach($array as $a)
{
echo $a[0] . '<br>';
}
}
echo_array_demo();
?>
I create items for an array $array and if i call it (foreach) without an function, it works. But if i call in in a function, then the error comes up...
I ve got no idea why
Thank you...
Functions have their own variable scope. Variables defined outside the function are not automatically known to it.
You can "import" variables into a function using the global keyword.
function echo_array_demo() {
global $array;
foreach($array as $a)
{
echo $a[0] . '<br>';
}
}
Another way of making the variable known to the function is passing it as a reference:
function echo_array_demo(&$array) {
foreach($array as $a)
{
echo $a[0] . '<br>';
}
}
echo_array_demo($array);
Check out the PHP manual on variable scope.

Categories