php - Is this an acceptable use of eval()?
Get the solution ↓↓↓I'm trying to use an imploded string as an operator. And as a PHP novice, eval() is the only option that works, so far.
I've read other questions/answers oneval()
. In most cases, people were trying to allow actual code input by the user, which is NOT what I'm doing here.
Here it is:
/*
* Get user choices from a multiple-select customizer custom control.
* Setting's choice values are the names of WordPress conditional tags.
* Each choice set is given as 'key'=>'label' NOT 'key'=>'function'
* so I'm limited to using strings here, e.g. is_front_page, is_singular.
* The result will be a linear array, e.g. array( is_front_page, is_singular ).
*/
$conditions = get_theme_mod( 'theme_setting' );
/*
* Here's where my trouble begins.
* I need to append `()` to each array value using array_walk. */
array_walk( $conditions, function(&$value, $key) { $value = $value . '()'; });
/*
* Next I implode the array values to insert the or operator
* So instead of "is_front_page, is_singular", I'd end up with
* "is_front_page() || is_singular()"
*/
$conditions = implode( ' || ', $conditions );
/* The previous step is NOT usable, in my novice experience, hence eval() */
eval( '$conditions = ' . $conditions . ';');
/* Eval makes the following usable */
if( $conditions ) {
// do stuff here
}
I'm hoping this is acceptable because I'm not allowing code input from the user and my theme setting is static so I can't actually do something like$conditions === true
as a workaround.
Even if it is acceptable, please let me know if you have any advice on how to improve it.
Answer
Solution:
Nooo... You are thinking too broadly. You have an array of function names and you jumped too far to executing them as freeform code.
Actually function names are valid callbacks and those are much safer and easier to execute withcall_user_func()
. So simplyarray_map('call_user_func', $conditions)
will turn all callbacks into their return values.
But note that your desired condition is of OR type. We don't need to run every callback, we only need to execute them until we get firsttrue
one.
This can be expressed as:
$result = array_reduce( $callbacks, function ( $carry, $callback ) {
return $carry ?: (boolean) call_user_func( $callback );
}, false );
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: trying to access array offset on value of type bool
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.