why the variable value changed to array into function scope ? PHP - php

why the variable $ replaced changed to array in a function ?
foreach ($rowset as $row)
{
$replaced = str_replace('$uid',$this->bbcode_uid,$row['first_pass_replace']);
echo $replaced; // this is a test of the variable error and it's ok
$this->bbcodes[$row['bbcode_tag']] = array(
'bbcode_id' => (int) $row['bbcode_id'],
'regexp' => array($row['first_pass_match'] => function($replaced){
return $replaced; //this is not working
}
)
);
}

I honestly have no idea what you are trying to accomplish but to make it "work" you need:
...
'regexp' => array(
$row['first_pass_match'] => function() use($replaced) {
return $replaced;
}
)
...
You use use() to achieve closure and bring an external variable into the function without explicitly passing it in as a parameter.

Related

PHP - Put variables with a prefix into array

Is there any way of putting variables into an array? I'm not really sure how else to explain it.
I'm developing a website that works with a game server.
The game exports a file which contains variables such as:
$RL_PlayerScore_CurrentTrail_14911 = "lasergold";
$RL_PlayerScore_HasTrail_14911_LaserGold = 1;
$RL_PlayerScore_Money_14911 = 2148;
I'd like to convert these into an array like
$data = array(
'CurrentTrail_14911' => 'lasergold'
'HasTrail_14911_LaserGold' => '1'
'Money_14911' => '2184'
);
Is there any way I could do this?
Thanks in advance
Include file in scope and then get array of defined vars, excluding globals you don't need.
include('name-of-your-file.php');
$data = get_defined_vars();
$data = array_diff_key($data, array(
'GLOBALS' => 1,
'_FILES' => 1,
'_COOKIE' => 1,
'_POST' => 1,
'_GET' => 1,
'_SERVER' => 1,
'_ENV' => 1,
'ignore' => 1 )
);
You can return an array with all your declared variables, and loop through them cutting off the desired piece of text. You could do something like this:
<?php
//echo your generated file here;
$generatedVars = get_defined_vars();
$convertedArray = array();
foreach($generatedVars as $key=>$var)
{
$key = str_replace("RL_PlayerScore_","",$key);
$convertedArray[$key] = $var;
}
If all game variables are going to begin with 'RL_PlayerScore_', you could use something like that :
$vars = [];
foreach($GLOBALS as $var => $value) {
if(strpos($var, 'RL_PlayerScore_') === 0) {
$vars[$var] = $value;
}
}
$vars will be filled by all your variables.
See #Dagon comment also.

Get Value from Array as Array Key

How do I recursively get value from array where I need to explode a key?
I know, it's not good the question, let me explain.
I got an array
[
"abc" => "def",
"hij" => [
"klm" => "nop",
"qrs" => [
"tuv" => "wxy"
]
]
]
So, inside a function, I pass:
function xget($section) {
return $this->yarray["hij"][$section];
}
But when I want to get tuv value with this function, I want to make section as array, example:
To get hij.klm value (nop), I would do xget('klm'), but to get hij.klm.qrs.tuv, I can't do xget(['qrs', 'tuv']), because PHP consider $section as key, and does not recursively explode it. There's any way to do it without using some ifs and $section[$i] ?
function xget($section) {
return $this->yarray["hij"][$section];
}
that one is static function right?
you can do that also for this
function xget($section) {
if(isset($this->yarray["hij"][$section])){
return $this->yarray["hij"][$section];
}elseif(isset($this->yarray["hij"]["klm"]["qrs"][$section])){
return $this->yarray["hij"]["klm"]["qrs"][$section];
}
}
as long as the key name between two of them are not the same.
You could use array_walk_recursive to find tuv's value regardless of the nested structure:
$tuv_val='';
function find_tuv($k,$v)
{
global $tuv_val;
if ($k=='tuv')
$tuv_val=$v;
}
array_walk_recursive($this->yarray,"find_tuv");
echo "the value of 'tuv' is $tuv_val";
try my code
<?php
$array = array(
'aaa' => 'zxc',
'bbb' => 'asd',
'ccc' => array(
'ddd' => 'qwe',
'eee' => 'tyu',
'fff' => array(
'ggg' => 'uio',
'hhh' => 'hjk',
'iii' => 'bnm',
),
),
);
$find = '';
function xget($key){
$GLOBALS['find'] = $key;
$find = $key;
array_walk_recursive($GLOBALS['array'],'walkingRecursive');
}
function walkingRecursive($value, $key)
{
if ($key==$GLOBALS['find']){
echo $value;
}
}
xget('ggg');
?>

Setting an array's value via a function's return value

I have an array that values are dynamically obtained from a function(or supposed to be), you may see example below. But looks like it doesn't work as expected. Is this usage wrong ?
$products = array(
"saloon" => array(
array(
"id" => "23544",
"precise" => "unkown",
"pump" => "auto",
"density" => "5:3",
"name" => "Multi dose arranger",
"color" => "224,0,92",
"desc" => "....",
"cdate" => "12342315",
"support" => "#lab"
)// Goes like this.
)
),
"basic" => array(
//Goes on and on
),
"variable" => array(
)
);
array(
2=> array(
getProduct(16,"everyday"),
getProduct(24,"everyday")
),
3=> array(
getProduct(16,"everyday"),
getProduct(23,"everyday")
),
4=> array(
getProduct(16,"everyday"),
getProduct(24,"everyday")
)
);
function getProduct($id,$cat){
GLOBAL $products,$a;
// echo $a;
// print_r(is_array($products));
foreach ($products[$cat] as $product) {
if($product["id"]==$id){
$selectedProduct = $product;
break;
}
}
return $selectedProduct;
}
function is like above but setts nothing, also printing array is also return empty.
Change your function for that:
function getProduct($id,$cat){
global $products,$a;
foreach ($products[$cat] as $product) {
if($product["id"]==$id){
$selectedProduct = $product;
break; //Instead of exit
}
}
return $selectedProduct;
}
Don't use exit because you want to break the execution of the foreach, not exit the program, use break instead.
EDIT: Corrected what the exit function does, thanks to #deceze
What you do wrong is using exit inside your function (it stops the whole script execution). You should change your function into:
function getProduct($id,$cat){
global $products,$a;
// echo $a;
// print_r(is_array($products));
foreach ($products[$cat] as $product) {
if($product["id"]==$id){
return $product;
}
}
return false;
}
In fact you don't need exit or break because you can simple return $product when you find it. You should also return value in case you don't find any product. In above example false is returned in that case.

use strings to access (potentially large) multidimensional arrays

I am having trouble figuring out a way to simply parse a string input and find the correct location within a multidimensional array.
I am hoping for one or two lines to do this, as the solutions I have seen rely on long (10-20 line) loops.
Given the following code (note that the nesting could, in theory, be of any arbitrary depth):
function get($string)
{
$vars = array(
'one' => array(
'one-one' => "hello",
'one-two' => "goodbye"
),
'two' => array(
'two-one' => "foo",
'two-two' => "bar"
)
);
return $vars[$string]; //this syntax isn't required, just here to give an idea
}
get("two['two-two']"); //desired output: "bar". Actual output: null
Is there a simple use of built-in functions or something else easy that would recreate my desired output?
Considering $vars being your variables you would like to get one['one-one'] or two['two-two']['more'] from (Demo):
$vars = function($str) use ($vars)
{
$c = function($v, $w) {return $w ? $v[$w] : $v;};
return array_reduce(preg_split('~\[\'|\'\]~', $str), $c, $vars);
};
echo $vars("one['one-one']"); # hello
echo $vars("two['two-two']['more']"); # tea-time!
This is lexing the string into key tokens and then traverse the $vars array on the keyed values while the $vars array has been turned into a function.
Older Stuff:
Overload the array with a function that just eval's:
$vars = array(
'one' => array(
'one-one' => "hello",
'one-two' => "goodbye"
),
'two' => array(
'two-one' => "foo",
'two-two' => "bar"
)
);
$vars = function($str) use ($vars)
{
return eval('return $vars'.$str.';');
};
echo $vars("['one']['one-two']"); # goodbye
If you're not a fan of eval, change the implementation:
$vars = function($str) use ($vars)
{
$r = preg_match_all('~\[\'([a-z-]+)\']~', $str, $keys);
$var = $vars;
foreach($keys[1] as $key)
$var = $var[$key];
return $var;
};
echo $vars("['one']['one-two']"); # goodbye
How about
$vars = array(
'one' => array(
'one-one' => "hello",
'one-two' => "goodbye"
),
'two' => array(
'two-one' => "foo",
'two-two' => "bar"
)
);
function get( $string, $vars )
{
$keys = explode( '][', substr( $string, 1, -1 ) );
foreach( $keys as $key ) {
$vars = $vars[$key];
}
return $vars;
}
echo get( '[two][two-one]', $vars );
For one, you've not got a $var in your get() function. $var was defined outside the function, and PHP scoping rules do not make "higher" vars visible in lower scopes unless explictly made global in the lower scope:
function get($string) {
global $vars;
eval('$x = $vars' . $string);
return $x;
}
get("['two']['two-two']");
might work, but this isn't tested, and using eval is almost always a very bad idea.
Kohana has a nice Config class which alows something like this:
echo Config::get("two.two-two");
You can check it out here: http://kohanaframework.org/3.1/guide/api/Config

How to combine the keys and values of an array in PHP

Say I have an array of key/value pairs in PHP:
array( 'foo' => 'bar', 'baz' => 'qux' );
What's the simplest way to transform this to an array that looks like the following?
array( 'foo=bar', 'baz=qux' );
i.e.
array( 0 => 'foo=bar', 1 => 'baz=qux');
In perl, I'd do something like
map { "$_=$hash{$_}" } keys %hash
Is there something like this in the panoply of array functions in PHP? Nothing I looked at seemed like a convenient solution.
Another option for this problem: On PHP 5.3+ you can use array_map() with a closure (you can do this with PHP prior 5.2, but the code will get quite messy!).
"Oh, but on array_map()you only get the value!".
Yeah, that's right, but we can map more than one array! :)
$arr = array( 'foo' => 'bar', 'baz' => 'qux' );
$result = array_map(function($k, $v){
return "$k=$v";
}, array_keys($arr), array_values($arr));
function parameterize_array($array) {
$out = array();
foreach($array as $key => $value)
$out[] = "$key=$value";
return $out;
}
A "curious" way to do it =P
// using '::' as a temporary separator, could be anything provided
// it doesn't exist elsewhere in the array
$test = split( '::', urldecode( http_build_query( $test, '', '::' ) ) );
chaos' answer is nice and straightfoward. For a more general sense though, you might have missed the array_map() function which is what you alluded to with your map { "$_=$hash{$_}" } keys %hash example.

Categories