I want to try and write a function to automate some of the legwork in checking/declaring a variable i.e.
function checkVariable($var)
{
if(!isset($var)||empty($var))
{
return '';
}
else
{
return $var;
}
}
$myvar = checkVariable($myvar);
obviously, this isn't going to work, because the variable doesn't exist prior to declaration and throws an error when you use it as an argument - sooooo, is there a way of doing this?
Pass the variable by reference:
function checkVariable(&$var) {
// …
}
I tend to use
$myvar = (isset($myvar) && !empty($myvar)) ? $myvar : '';
But if you have to do this a lot, and you want to use a function, Gumbo's suggestion is right.
Related
I think the below is a very standard procedure that everyone had written it a hundred times in any of their applications:
$orderByColumnName = '';
if (isset($this->urlParams()['orderby']) {
$orderByColumnName = $this->urlParams()['orderby'];
}
$this->someSortingFunction($orderByColumnName);
I've been doing such way numerous time, I'm feeling sick of it.
There's some kind of like global understanding that suppressing error is evil.
Despite the code can be written so clean by just:
$this->someSortingFunction(#$this->urlParams()['orderby']);
And a ternary shorthand true ?: false; is something close but not useful in this situation because there's no presumed isset check on the condition. Thus we still have to write:
$orderByColumnName = !empty($this->urlParams()['orderby'])?$this->urlParams()['orderby']:'';
So how exactly you guys handle this situation? if all the way? Is there any other smarter way that you could share?
Why not change how the urlParams() method operates? PHP doesn't have true method overloading, but you can fake it inside the method.
public function urlParam($param = null) {
//lets assume $internal_array is
//your object's internal array sent through urlParam()
if(is_null($param)) {
return $internal_array;
} else {
return isset($internal_array[$param]) ? $internal_array[$param] : '';
}
}
Doing this would let you you keep your existing code compatible with $this->urlParams()['some_param']usage while enabling you to refactor everything to $this->urlParams('some_param').
Here is a separate static function which returns NULL if value is not present in an array.
public static function value($key, $list, $default = NULL) {
if (is_array($list)) {
return array_key_exists($key, $list) ? $list[$key] : $default;
}
return $default;
}
Can call this everytime we need to use empty(), isset(), array_key_exists()
$this->someSortingFunction(value('orderby', $this->urlParams()));
I have the following code in numerous places (thousands of places) around my project:
$foo = isset($mixed) ? $mixed : null;
Where $mixed can be anything: array, array element, object, object property, scalar, etc. For example:
$foo = isset($array['element']) ? $array['element'] : null;
$foo = isset($nestedArray['element']['key']) ? $nestedArray['element']['key'] : null;
$foo = isset($object->prop) ? $object->prop : null;
$foo = isset($object->chain->of->props) ? $object->chain->of->props : null;
Is there a way to write this repeated logic as a (simple) function? For example, I tried:
function myIsset($mixed)
{
return isset($mixed) ? $mixed : null;
}
The above function looks like it would work, but it does not in practice. For example, if $object->prop does not exist, and I call myIsset($object->prop)), then I get fatal error: Undefined property: Object::$prop before the function has even been called.
Any ideas on how I would write such a function? Is it even possible?
I realize some solutions were posted here and here, but those solutions are for arrays only.
PHP 7 has a new "Null coalescing operator" which does exactly this. It is a double ?? such as:
$foo = $mixed ?? null;
See http://php.net/manual/en/migration70.new-features.php
I stumbled across the answer to my own question while reading about php references. My solution is as follows:
function issetValueNull(&$mixed)
{
return (isset($mixed)) ? $mixed : null;
}
Calls to this function now look like:
$foo = issetValueNull($array['element']);
$foo = issetValueNull($nestedArray['element']['key']);
$foo = issetValueNull($object->prop);
$foo = issetValueNull($object->chain->of->props);
Hopefully this helps anyone out there looking for a similar solution.
isset is a language construct, not a regular function. Therefore, it can take what would otherwise cause an error, and just return false.
When you call myIsset($object->prop)), the evaluation occurs and you get the error.
See http://php.net/manual/en/function.isset.php
This is the same problem as using typeof nonExistentVariable in JavaScript. typeof is a language construct and will not cause an error.
However, if you try to create a function, you get an error for trying to use an undefined variable.
function isDef(val) {
return typeof val !== 'undefined';
}
console.log( typeof nonExistent !== 'undefined'); // This is OK, returns false
isDef(nonExistent); // Error nonExistent is not defined
You could actually just write it like:
$foo = $mixed?:null;
If you just want to check if it exist do this
function myIsset($mixed)
{
return isset($mixed); // this is a boolean so it will return true or false
}
function f(&$v)
{
$r = null;
if (isset($v)) {
$r = $v;
}
return $r;
}
I am looking to come up with a function which will return based on how it is called.
If I call the function from within a php class or function, it will return an array, whereas if it was called from within an eval() statement then it will return a string.
Say the function is as:
function GetName(){
return isEval ? 'John Doe' : array('John','Doe');
}
Is it possible to replace the isEval with something to detect if it was called from within eval() ?
Update:
This is going to be part of a CMS system. I need to provide some already builtin functions to become available publicly. I know the security risks would arise using eval(), but still would like to know if it is possible in anyway.
Passing in parameter for sure works perfectly, but as described above, dont want to get abused by providing that option.
The only function that contains information you want is debug_backtrace. So you can do something like:
function getName(){
$debug = debug_backtrace();
//check $debug array. I think it should
//be in the 2nd element of array:
if ($debug[1]['function'] == 'eval') {
//Do Eval stuff.
}
}
Why not add an argument in your function? True if eval, false if not.
function GetName(eval){
if(eval)
//TODO IF EVAL
else
//TODO IF NOT EVAL
}
When you are calling from eval pass true as parameter, following function should work.
function GetName(isEval = false){
return isEval ? 'John Doe' : array('John','Doe');
}
Given the two answers here already, suggesting passing an argument to the function, it got me thinking about overloading the function, so you could personally pass it another argument to show that it isn't being passed via an eval() but of course PHP doesn't support function overloading.
However you could write your function to accept an optional parameter, then use func_num_args() and func_get_arg() to determine what has been sent. If the optional parameter isn't being sent, you could easily and safely assume that it is being eval()'ed and you can make it act accordingly.
function isEval()
{
foreach(array_reverse(debug_backtrace()) as $v) {
return $v['function'] === 'eval';
}
}
function isEval() { // updated by code90
foreach(array_reverse(debug_backtrace()) as $v) {
if($v['function'] === 'eval') return true;
}
return false; }
function myFunc()
{
return isEval() ? "is eval\n" : "is not eval\n";
}
function callAnotherFunction()
{
return myFunc();
}
function myFunctionWithEval()
{
eval('$return = myFunc();');
return $return;
}
Test
echo "myFunc() without eval: " . myFunc();
eval("echo 'myFunc() whit eval: ' . myFunc();");
echo "callAnotherFunction() without eval: " . callAnotherFunction();
eval("echo 'callAnotherFunction() with eval: ' . callAnotherFunction();");
echo 'myFunctionWithEval() with eval: ' . myFunctionWithEval();
Output
myFunc() without eval: is not eval
myFunc() whit eval: is eval
callAnotherFunction() without eval: is not eval
callAnotherFunction() with eval: is eval
myFunctionWithEval() with eval: is not eval <--- PROBLEM!
myFunctionWithEval call myFunc with eval. You can not guarantee when it was called eval. Can give false positive.
You should think of another way to proceed. This methodology should not be used!
An alternative, but I always recommend not to use:
function isEval()
{
return isset($GLOBALS['__MyEval']) && $GLOBALS['__MyEval'] === true;
}
function myFunc()
{
return isEval() ? "is eval\n" : "is not eval\n";
}
function myFunctionWithEval()
{
$GLOBALS['__MyEval'] = true;
eval('$return = myFunc();');
$GLOBALS['__MyEval'] = null;
return $return;
}
echo "myFunctionWithEval() with eval: " . myFunctionWithEval();
I'm writing quite often this line of code:
$myParam = isset($params['myParam']) ? $params['myParam'] : 'defaultValue';
Typically, it makes the line very long for nested arrays.
Can I make it shorter?
function getOr(&$var, $default) {
if (isset($var)) {
return $var;
} else {
return $default;
}
}
$myParam = getOr($params['myParam'], 'defaultValue');
Be sure to pass the variable by reference though, otherwise the code will produce a E_NOTICE. Also the use of if/else instead of a ternary operator is intentional here, so the zval can be shared if you are using PHP < 5.4.0RC1.
PHP 7 will contain ?? operator that does exactly that.
See https://wiki.php.net/rfc/isset_ternary, example:
// Fetches the request parameter user and results in 'nobody' if it doesn't exist
$username = $_GET['user'] ?? 'nobody';
// equivalent to: $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
Yes, by making a proxy function, but is it really worth it?
Also, isset is a language construct, so wrapping it in a proxy function will degrade performance, although the degradation will likely be less than trivial (not even really worth mentioning.)
This is what I use:
function getindex($arr, $index, $default = null) {
return isset($arr[$index]) ? $arr[$index] : $default;
}
As of PHP 5.3 you can use:
$myParam = $params['myParam'] ?: 'defaultValue';
Note, however, that $params['myParam'] and isset($params['myParam']) are not 100% the same.
I'm using little this little magic class which works as variable
class Post() {
private $post = Array();
public function __construct() {
$this->post = $_POST;
}
public function __get($name) {
return #$this->post[$name];
}
public function __set($name, $value) {
return $this->post[$name] = $value;
}
public function __call($function, $params) {
if(isset($this->post[$function])) {
return $this->post[$function];
} else {
$this->post[$function] = $params[0];
return $params[0];
}
}
}
$post = new Post();
then in document you can use it easily as any other variable so for example $post->name $post->somelist[2] or with default value $post->name("John Doe") and after that you got it returned as well as stored.
I know this doesn't shorten anything up for you but thought I'd just share this, I use this alot in my applications to make sure something is set and has a value.
function is_blank($var = NULL){
return empty($var) && !is_numeric($var) && !is_bool($var);
}
function chk_var($var = NULL){
return (isset($var) && !is_null($var) && !is_blank($var));
}
Then...
if(chk_var($myvar)){ ... }
No. Unfortunately, you can't. Not in a decent way. You'll at least have to give in on performance.
Update: since PHP7, ?? will do just that. See https://wiki.php.net/rfc/isset_ternary
You if you have to do it often, you are probably missing the point.
In fact, variables should be defined before use.
So, there oughtn't be a case when you have your param undefined.
Just create a default params file, and initialize every your variable.
$params['myParam'] = 'defaultValue';
later it can be changed under some circunstances but it never be undefined.
Got the idea?
I find in my PHP pages I end up with lines and lines of code that look like this:
$my_id = isset($_REQUEST['my_id']) ? $_REQUEST['my_id'] : '';
$another_var = isset($_REQUEST['another_var']) ? $_REQUEST['another_var'] : 42;
...
Is there a better, more concise, or more readable way to check this array and assign them to a local variable if they exist or apply a default if they don't?
EDIT: I don't want to use register_globals() - I'd still have the isset problem anyway.
How about wrapping it in a function?
<?php
function getPost($name, $default = null) {
return isset($_POST[$name]) ? $_POST[$name] : $default;
}
a better method might be to create a singleton/static class to abstract away the details of checking the request data.
Something like:
class Request {
private $defaults = array();
private static $_instance = false;
function getInstance () {
if (!self::$_instance) {
$c = __CLASS__;
self::$_instance = new $c;
}
return self::$_instance;
}
function setDefaults($defaults) {
$this->defaults = $defaults;
}
public function __get($field) {
if (isset($_REQUEST[$field]) && !empty($_REQUEST[$field])) {
return $_REQUEST['field'];
} elseif (isset($this->defaults[$field])) {
return $this->defaults[$field];
} else {
return ''; # define a default value here.
}
}
}
you can then do:
# get an instance of the request
$request = Request::getInstance();
# pass in defaults.
$request->setDefaults(array('name'=>'Please Specify'));
# access properties
echo $request->name;
echo $request->email;
I think this makes your individual scripts loads cleaner and abstracts away the validation etc. Plus loads of scope with this design to extend it/add alternate behaviours, add more complicated default handling etc etc.
First, use $_POST for POSTed variables. $_REQUEST is a mashup of many different incoming variables, not just $_POST and could cause problems.
One solution for your question would be to create a function that handles the isset() logic.
function ForceIncomingValue($Key, $Default) {
if (!isset($_POST[$Key]))
return $Default;
else return $_POST[$Key];
}
first of all, NEVER use the $_REQUEST variable, it'll lead to bugs and other problems during development
function getPOST($key) {
if(isset($_POST[$key])) {
return $_POST[$key];
}
}
note that this code leaves the variable empty when $_POST[$key] was not set
you could also adapt that code to enable you to instead provide you with a (sensible) default when the value could not be loaded.
function getPOST($key, $default = NULL) {
if(isset($_POST[$key])) {
return $_POST[$key];
} else {
return $default;
}
}
Is the set of variables you're expecting known at the time of the script's writing, or do you want to do this for an arbitrary set of values? If the former is true, you could do something like this:
# This array would hold the names of all the variables you're expecting
# and a default value for that variable name
$variableNames = array (...);
foreach ($variableNames as $key => $default) {
if (isset ($_REQUEST[$key])) $$key = $_REQUEST[$key];
else $$key = $default;
}
Basically, this takes advantage of PHP's ability to evaluate variables to create other variables (hence the double-dollar for $$key--this means create a new variable whose name is the value of $key).
I haven't yet come up with a good solution to the latter situation.
PHP's null coalescing operator!
$username = $_GET['user'] ?? 'nobody';
For a lot of variables, with a requirement check, anyone is free to use my expect function.