I want to read a variable from inside a weird function that I copied from this git .
This is the original function:
$values = array_map(function ($value) use ($connection) {
if ($value===null) return null;
// return mysqli_real_escape_string($connection,(string)$value);
return pg_escape_string($connection,(string)$value);
},array_values($input));
and I changed it into this in order to adapt it to my needs (file upload)
$values = array_map(function ($value) use ($connection) {
if ($value === null)
return null;
if (gettype($value) === "array"){
$tmpname=$value['tmp_name'];
$value=$value['name'];
}
return mysqli_real_escape_string($connection, (string) $value);
}, array_values($input));
The problem is that I can't read $tmpname from outside this function.
Can anyone help me?
So the answer as #rtfm said is to set a global var like this
$values = array_map(function ($value) use ($connection) {
if ($value === null)
return null;
if (gettype($value) === "array"){
global $tmpname;
$tmpname=$value['tmp_name'];
$value=$value['name'];
}
return mysqli_real_escape_string($connection, (string) $value);
}, array_values($input));
Related
This question already has answers here:
How to use return inside a recursive function in PHP
(4 answers)
Closed 9 months ago.
I have two of these methods. The get_value_from_raw_data method, if found by the key, should return a value, but it always returns false.
public function get_value_from_raw_data($associative_key , $haystack) {
foreach ($haystack as $key => $value) {
if (! is_array($value)) {
if ($key === $associative_key) {
return $value;
} else {
continue;
}
} else if (is_array($value)) {
$this->get_value_from_raw_data($associative_key , $haystack[$key]);
}
}
return false;
}
private function convert_value($value) {
$new_value = $this->get_value_from_raw_data($value['associative_key'] , $this->raw_data);
if ($value['path_to'] !== "") {
$paths = explode('.' , $value['path_to']);
$temp = &$this->used_model;
foreach ($paths as $key) {
$temp = &$temp[$key];
}
$temp[$value['key_name']] = $new_value;
} else {
$this->used_model[$value['key_name']] = $new_value;
}
}
Also, if I use dd inside this method before return, then it displays the value, and after return it is already gone.
You're not returning the value when you make a recursive call to the function:
else if (is_array($value)) {
$this->get_value_from_raw_data($associative_key , $haystack[$key]);
}
should be:
else if (is_array($value)) {
return $this->get_value_from_raw_data($associative_key , $haystack[$key]);
}
I got a problem.
I make a function to update my config.json file.
The problem is, my config.json is a multdimensional array. To get a value of a key i use this function:
public function read($key)
{
$read = explode('.', $key);
$config = $this->config;
foreach ($read as $key) {
if (array_key_exists($key, $config)) {
$config = $config[$key];
}
}
return $config;
}
I also made a function to update a key. But the problem is if i make update('database.host', 'new value'); it dont updates only that key but it overrides the whole array.
This is my update function
public function update($key, $value)
{
$read = explode('.', $key);
$config = $this->config;
foreach ($read as $key) {
if (array_key_exists($key, $config)) {
if ($key === end($read)) {
$config[$key] = $value;
}
$config = $config[$key];
}
}
print_r( $config );
}
my config.json looks like this:
{
"database": {
"host": "want to update with new value",
"user": "root",
"pass": "1234",
"name": "dev"
},
some more content...
}
I have a working function but thats not really good. I know that the max of the indexes only can be three, so I count the exploded $key and update the value:
public function update($key, $value)
{
$read = explode('.', $key);
$count = count($read);
if ($count === 1) {
$this->config[$read[0]] = $value;
} elseif ($count === 2) {
$this->config[$read[0]][$read[1]] = $value;
} elseif ($count === 3) {
$this->config[$read[0]][$read[1]][$read[3]] = $value;
}
print_r($this->config);
}
Just to know: the variable $this->config is my config.json parsed to an php array, so nothing wrong with this :)
After I had read your question better I now understand what you want, and your read function, though not very clear, works fine.
Your update can be improved though by using assign by reference & to loop over your indexes and assign the new value to the correct element of the array.
What the below code does is assign the complete config object to a temporary variable newconfig using call by reference, this means that whenever we change the newconfig variable we also change the this->config variable.
Using this "trick" multiple times we can in the end assign the new value to the newconfig variable and because of the call by reference assignments the correct element of the this->config object should be updated.
public function update($key, $value)
{
$read = explode('.', $key);
$count = count($read);
$newconfig = &$this->config; //assign a temp config variable to work with
foreach($read as $key){
//update the newconfig variable by reference to a part of the original object till we have the part of the config object we want to change.
$newconfig = &$newconfig[$key];
}
$newconfig = $value;
print_r($this->config);
}
You can try something like this:
public function update($path, $value)
{
array_replace_recursive(
$this->config,
$this->pathToArray("$path.$value")
);
var_dump($this->config);
}
protected function pathToArray($path)
{
$pos = strpos($path, '.');
if ($pos === false) {
return $path;
}
$key = substr($path, 0, $pos);
$path = substr($path, $pos + 1);
return array(
$key => $this->pathToArray($path),
);
}
Please note that you can improve it to accept all data types for value, not only scalar ones
I have a function called get_config() and an array called $config.
I call the function by using get_config('site.name') and am looking for a way to return the value of $config so for this example, the function should return $config['site']['name'].
I'm nearly pulling my hair out - trying not to use eval()! Any ideas?
EDIT: So far I have:
function get_config($item)
{
global $config;
$item_config = '';
$item_path = '';
foreach(explode('.', $item) as $item_part)
{
$item_path .= $item."][";
$item = $config.{rtrim($item_path, "][")};
}
return $item;
}
This should work:
function get_config($config, $string) {
$keys = explode('.', $string);
$current = $config;
foreach($keys as $key) {
if(!is_array($current) || !array_key_exists($key, $current)) {
throw new Exception('index ' . $string . ' was not found');
}
$current = $current[$key];
}
return $current;
}
you could try something like...
function get_config($item)
{
global $config;
return $config[{str_replace('.','][',$item)}];
}
Inside your get_config function, you can parse the string using explode function in php
function get_config($data){
$pieces = explode(".", $data);
return $config[$pieces[0]][$pieces[1]];
}
I'm sure this is an easy solution - I wrote found this endswith function and thought I'd try the array_walk function instead of testing each string separately. I'd assumed that the result of the array_walk function would be false but it returns 1...How do I get it to test all the strings and return false if it didn't find a match? Thanks
class {
function endsWith($value,$key,$haystack)
{
$length = strlen($value);
if ($length == 0) {
return true;
}
return (substr($haystack, -$length) === $value);
}
function thing()
{
$email = "should#returnfalse.info";
$arr = array("#test.net","#test.org.uk","#test.co.uk","#test.com");
echo array_walk($arr,array($this,"endsWith"),$email);
}
}
The return value of array_walk is not determined by whatever the callback does; it only informs you if walking the entire array was completed successfully.
You may want to look into a few alternatives.
This will return the number of matching elements and will also serve as a boolean test, but it will evaluate every element no matter what:
echo count(array_filter($arr,array($this,"endsWith")));
This will stop evaluating elements with endsWith as soon as a match is detected and will return true if there is a match, false otherwise:
$self = $this;
// cast to int because false is printed as the empty string
echo (int)array_reduce($arr,
function($result, $v) use ($email, $self) {
return $result || $self->endsWith($v, null, $email);
},
false);
Try this
class {
function thing()
{
$email = "should#returnfalse.info";
$arr = array("#test.net","#test.org.uk","#test.co.uk","#test.com");
foreach ($arr as $domain) {
$length = strlen($value);
if ($length != 0) {
if (substr($email, -$length) === $domain) { echo $domain; break; }
}
}
}
}
array_walk() just iterates over the elements of an array and returns true, if it was able to do it. (echo casts boolea true to a string '1') Have a look at array_recude()
$that = $this; // Cannot access $this directly before PHP 5.4
var_dump(
array_reduce (
$arr,
function($result, item) use ($email, $that) { return $result || $that->endsWith($item, null /* not used anyway */, $email);},
false
)
);
Additional $key is not used and useless in endsWith().
If you want to apply a function to all values and return a single result you should use array_reduce.
As of PHP 5.3, you can use anonymous functions:
class {
function thing()
{
$email = "should#returnfalse.info";
$arr = array("#test.net","#test.org.uk","#test.co.uk","#test.com");
$match = '';
$found = false;
array_walk($arr,function($value) use (&$match, &$found, $email) {
$length = strlen($value);
if ($length == 0) {
$found = true;
return;
}
if (substr($email, -$length) === $value) {
$match = $value;
$found = true;
}
});
if ($found) {
echo 'Found match: ' . $match;
} else {
echo 'No match found :(';
}
}
}
$name= path1
$key= key1
public static function getpath($name, $key)
{
if (!self::is_valid($name, $key)) return false;
$path = '/var/lib/fdata/'.$name.'/'.$key;
if (!is_file($path)) return false;
return $path;
}
public static function get($name, $key)
{
$path = self::getpath($name, $key);
if ($path === false) return false;
return file_get_contents($path);
}
$configmap = unserialize(fdata::get('base', 'key'));
The questions is:
if variable $path = self::getpath($name, $key); then $path = ? and what mean self::
if variable $configmap = unserialize(fdata::get('base', 'key')); then $configmap = ? and what mean fdata::
1) self::getpath(...) should return a boolean value or a string. self:: refers to a current class.
2) Here's the man for unserialize
3)
fdata:: denotes the namespace fdata or perhaps a class.