In PHP Consider this function:
function test($name, $age) {}
I need to somehow extract the parameter names (for generating custom documentations automatically) so that I could do something like:
get_func_argNames('test');
and it would return:
Array['name','age']
Is this even possible in PHP?
You can use Reflection :
function get_func_argNames($funcName) {
$f = new ReflectionFunction($funcName);
$result = array();
foreach ($f->getParameters() as $param) {
$result[] = $param->name;
}
return $result;
}
print_r(get_func_argNames('get_func_argNames'));
//output
Array
(
[0] => funcName
)
It's 2019 and no one said this?
Just use get_defined_vars():
class Foo {
public function bar($a, $b) {
var_dump(get_defined_vars());
}
}
(new Foo)->bar('first', 'second');
Result:
array(2) {
["a"]=>
string(5) "first"
["b"]=>
string(6) "second"
}
This is an old question I happened on looking for something other then Reflection, but I will toss out my current implementation so that it might help someone else. Using array_map
For a method
$ReflectionMethod = new \ReflectionMethod($class, $method);
$params = $ReflectionMethod->getParameters();
$paramNames = array_map(function( $item ){
return $item->getName();
}, $params);
For a function
$ReflectionFunction = new \ReflectionFunction('preg_replace');
$params = $ReflectionFunction->getParameters();
$paramNames = array_map(function( $item ){
return $item->getName();
}, $params);
echo '<pre>';
var_export( $paramNames );
Outputs
array(
'0' => 'regex',
'1' => 'replace',
'2' => 'subject',
'3' => 'limit',
'4' => 'count'
)
Cheers,
In addition to Tom Haigh's answer if you need to get the default value of optional attributes:
function function_get_names($funcName){
$attribute_names = [];
if(function_exists($funcName)){
$fx = new ReflectionFunction($funcName);
foreach ($fx->getParameters() as $param){
$attribute_names[$param->name] = NULL;
if ($param->isOptional()){
$attribute_names[$param->name] = $param->getDefaultValue();
}
}
}
return $attribute_names;
}
Useful for variable type validation.
#Tom Haigh, or do it more classy:
function getArguments( $funcName ) {
return array_map( function( $parameter ) { return $parameter->name; },
(new ReflectionFunction($funcName))->getParameters() );
}
// var_dump( getArguments('getArguments') );
func_get_args
function my($aaa, $bbb){
var_dump( func_get_args() );
}
my("something","something"); //result: array('aaa' => 'something', 'bbb' => 'something');
also, there exists another global functions: get_defined_vars(), that returns not only function, but all variables.
Related
$alllist = array(
"link" => $link,
"title" => $title,
"imgurl" => $imgURL,
"price" => $price,
"mname" => $merchantname,
"description" => $description,
);
$all[] = $alllist;
I am trying to filter the array $all where mname is a certain value, let's say 'Amazon'. How do I do that?
I tried this, but it did not work:
reset($all);
$all_filter = array_filter($all, function(filter) use ($all) {
$key = key($all);
next($all);
return key($all) === 'Amazon';
});
I think this what you want:
$name = 'Amazon';
$all_filter = array_filter($all, function (array $item) use ($name) {
return array_key_exists('mname', $item) && $item['mname'] === $name;
});
$all[] = array("link"=> 1, "title"=> 2, "imgurl"=> 3,
"price"=>4, "mname"=>'Amazon', "description"=>5);
$all[] = array("link"=> 1, "title"=> 2, "imgurl"=> 3,
"price"=>4, "mname"=>'Facebook', "description"=>5);
$filtered = array_filter($all, function($item) {
return $item['mname'] === 'Amazon';
});
var_dump($filtered);
array_filter() will iterate over the array for you. You don't need to call reset() or next().
You should look at the array_filter() documentation for more info and examples.
$all_filter = array_filter($all, function($item) {
return $item['mname'] === 'Amazon';
});
It looks like you're making it more complex than it needs to be. The callback should just return a boolean value. If you don't want to hard-code the value you want to filter by (e.g. 'Amazon'), you can pass it into the callback with use.
$filter_value = 'Amazon';
$all_filter = array_filter($all, function($item) use($filter_value) {
// without use($filter_value), $filter_value will be undefined in this scope
return $item['mname'] == $filter_value;
});
Returning the boolean expression $item['mname'] == $filter_value; will determine which items have mname values that match the filter value, and those items will be included in the result.
Is is possible? Something like (which doesn't work) :
$prototype = array(
'ext' => function ($args)
{
$ext = NULL;
if (in_array(func_get_arg(0), array('js', 'css')))
return $ext;
else
return 'js';
},
);
Yes. The only limitation is that you can't cast it to an object.
<?php
$foo = array(
'bar' => function($text)
{
echo $text;
}
);
$foo['bar']('test'); //prints "test"
$obj = (object)$foo;
$obj->bar('test'); //Fatal error: Call to undefined method stdClass::bar() in /code/REGnPf on line 11
?>
It certainly is:
<?php
$array = array(
'func' => function($a) {
return $a + 2;
}
);
echo $array['func'](3);
?>
This will give you 5 =)!
I'm trying to make something like
function config( $string ){
require 'configuration.php';
return $config[$string];
}
but i have a problem when my config has a 2D array. like:
$config['features'] = array(
'memcached' => TRUE,
'compress' => TRUE,
'gzip' => TRUE
);
how can i get config('features/memcached') or if can we have three or more threaded array like config('features/memcached/version14/etc') ( example ) to return true but still works when we do something like config('features') returns the array just like the function above. any ideas ?
Just split the string into keys:
function config( $string ){
require 'configuration.php';
$keys = explode('/',$string);
$return = $config;
foreach($keys as $key){
$return = $return[$key];
}
return $return;
}
Here you can do this too:
config('features/others/foo/bar');
if this exists:
$config['features'] = array(
'memcached' => TRUE,
'others' => array( 'foo' => array( 'bar' => 42 ) )
);
function config( $string ){
require 'configuration.php';
$p = explode("/",$string);
$r = $config;
foreach($p as $param)
$r = $r[$param];
return $r;
}
you could try this (written from head, not tested):
function config( $key, $subkey = null ){
require 'configuration.php';
return ($subkey)? $config[$key][$subkey] : $config[$key];
}
use it as config('features','memcached') and note that this will only work with one level of sub-arrays. if there could be more or if you want to stick to the config('features/memcached')-syntax, you could try something like this (same as the function above - this isn't tested, maybe you'll have to fix a bug on your own ;) ):
function config( $string ){
require 'configuration.php';
$keys = explode('/',$string);
foreach($keys as $key){
$config = $config[$key];
}
return $config;
}
You can use that aproach:
public function config($path = null, $separator = '.')
{
if (!$path) {
return self::$_constants;
}
$keys = explode($separator, $path);
require 'configuration.php';
$value = $config;
foreach ($keys as $key) {
if (!isset($value[$key])) {
throw new Exception("Value for path $path doesn't exists or it's null");
}
$value = $value[$key];
}
return $value;
}
In your example calling config('features') will return array, and config('features.compres') will return true and so on.
I am trying to remove keys from array.
Here is what i get from printing print_r($cats);
Array
(
[0] => All > Computer errors > HTTP status codes > Internet terminology
[1] =>
Main
)
I am trying to use this to remove "Main" category from the array
function array_cleanup( $array, $todelete )
{
foreach( $array as $key )
{
if ( in_array( $key[ 'Main' ], $todelete ) )
unset( $array[ $key ] );
}
return $array;
}
$newarray = array_cleanup( $cats, array('Main') );
Just FYI I am new to PHP... obviously i see that i made mistakes, but i already tried out many things and they just don't seem to work
Main is not the element of array, its a part of a element of array
function array_cleanup( $array, $todelete )
{
$cloneArray = $array;
foreach( $cloneArray as $key => $value )
{
if (strpos($value, $todelete ) !== false)
unset( $array[ $key ] ); //$array[$key] = str_replace($toDelete, $replaceWith, $value) ; // add one more argument $replaceWith to function
}
return $array;
}
Edit:
with array
function array_cleanup( $array, $todelete )
{
foreach($todelete as $del){
$cloneArray = $array;
foreach( $cloneArray as $key => $value )
{
if (strpos($value, $del ) !== false)
unset( $array[ $key ] ); //$array[$key] = str_replace($toDelete, $replaceWith, $value) ; // add one more argument $replaceWith to function
}
}
return $array;
}
$newarray = array_cleanup( $cats, array('Category:Main') );
Wanted to note that while the accepted answer works there's a built in PHP function that handles this called array_filter. For this particular example it'd be something like:
public function arrayRemoveMain($var){
if ( strpos( $var, "Category:Main" ) !== false ) { return false; }
return true;
}
$newarray = array_filter( $cats, "arrayRemoveMain" );
Obviously there are many ways to do this, and the accepted answer may very well be the most ideal situation especially if there are a large number of $todelete options. With the built in array_filter I'm not aware of a way to pass additional parameters like $todelete so a new function would have to be created for each option.
It's easy.
$times = ['08:00' => '08:00','09:00' => '09:00','10:00' => '10:00'];
$timesReserved = ['08:00'];
$times = (function() use ($times, $timesReserved) {
foreach($timesReserved as $time){
unset($times[$time]);
}
return $times;
})();
The question is "how do I remove specific keys".. So here's an answer with array filter if you're looking to eliminate keys that contain a specific string, in our example if we want to eliminate anything that contains "alt_"
$arr = array(
"alt_1"=>"val",
"alt_2" => "val",
"good key" => "val"
);
function remove_alt($k) {
if(strpos($k, "alt_") !== false) {
# return false if there's an "alt_" (won't pass array_filter)
return false;
} else {
# all good, return true (let it pass array_filter)
return true;
}
}
$new = array_filter($arr,"remove_alt",ARRAY_FILTER_USE_KEY);
# ^ this tells the script to enable the usage of array keys!
This will return
array(""good key" => "val");
Example:
$arr = array(1 => 'Foo', 5 => 'Bar', 6 => 'Foobar');
/*... do some function so $arr now equals:
array(0 => 'Foo', 1 => 'Bar', 2 => 'Foobar');
*/
Use array_values($arr). That will return a regular array of all the values (indexed numerically).
PHP docs for array_values
array_values($arr);
To add to the other answers, array_values() will not preserve string keys. If your array has a mix of string keys and numeric keys (which is probably an indication of bad design, but may happen nonetheless), you can use a function like:
function reset_numeric_keys($array = array(), $recurse = false) {
$returnArray = array();
foreach($array as $key => $value) {
if($recurse && is_array($value)) {
$value = reset_numeric_keys($value, true);
}
if(gettype($key) == 'integer') {
$returnArray[] = $value;
} else {
$returnArray[$key] = $value;
}
}
return $returnArray;
}
Not that I know of, you might have already checked functions here
but I can imagine writing a simple function myself
resetarray($oldarray)
{
for(int $i=0;$i<$oldarray.count;$i++)
$newarray.push(i,$oldarray[i])
return $newarray;
}
I am little edgy on syntax but I guess u got the idea.