This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What is the PHP ? : operator called and what does it do?
I found the answer to something I was looking for, but I don't quite understand the syntax because they used, I think, short tags. Here is the code:
$temp = is_array($value) ? $value : trim($value);
Could someone explain how this works? I think this means if true, return the value and if false return the value trimmed, but I'm not sure. Can there be more than two options, or is it strictly true and false?
You are correct. This is a conditional operator, ?: is a ternary operator.
<?php
// Example usage for: Ternary Operator
$temp = is_array($value) ? $value : trim($value);
// The above is identical to this if/else statement
if (is_array($value)) {
$temp = $value;
} else {
$temp = trim($value);
}
?>
Take a look half way down this page for more information:
http://php.net/manual/en/language.operators.comparison.php
It is equivalent to
if (is_array($value)){
$temp = $value;
}
else{
$temp = trim($value);
}
More info: http://en.wikipedia.org/wiki/Ternary_operation
$condition ? true : false, the ? instruction is same as
if($condition)
true
else
false
so in your example the code is same as
if(is_array($value))
$temp = $value
else
$temp = trim($value);
It's basically the same as
if(is_array($value)) {
$temp = $value;
} else {
$temp = trim($value);
}
You are correct. If is_array($value) returns true then the expression sets $temp = $value otherwise $temp = trim($value).
Strictly two choices. You interpreted it correctly.
if (is_array($value)) $temp = $value;
else $temp = trim($value);
If you wanted to hack this syntax to have 3 values you could do $temp = (condition1) ? true : (condition2) ? true2 : false;
This is ternary operator. Its will convert exp before ? to a bool. If you want more option just combine multi ?:.
(con?trueorfalseiftrue:otherwise)? (con2?_:_):(con3?_:_)
Related
How to replace this :
if( $this->getInfo() ){
$value = $this->getInfo();
}else{
$value = $this->getAnotherInfo();
}
This would be nicer solution :
$value = $this->getInfo() ? $this->getInfo() : $this->getAnotherInfo();
But we repeat $this->getInfo().
Here is the fun:
$value = $this->getInfo() ? : $this->getAnotherInfo();
If it bothers you having to repeat the expression you could write a function that returns the first truthy value.
$value = which ($this->getInfo(), $this->getAnotherInfo());
function which () {
if (func_num_args()<1) return false;
foreach (func_get_args() as $s) if ($s) return $s;
return false;
}
A nasty option would be this:
if (!($value = $this->getInfo())) $value = $this->getOtherInfo();
If the assignment returns false assign the other value.
But aside from this looking disgusting, it is still repetitive, albeit in a different way.
As of PHP 5.3, you can leave out the middle part of the ternary operator and avoid the repetition:
$value = $this->getInfo() ? : $this->getOtherInfo();
Which does what you want.
So, as the title says... any alternative to:
$valid_times = array('ever', 'today', 'week', 'month');
if (($this->_time == 'ever') OR ($this->_time == 'day'))
OR
if (in_array($this->_time, $valid_times))
??
Note: I know the mentioned above works, but I'm just looking for new things to learn and experiment with
UPDATE
Thanks for the info, but I didn't mentioned switch() as an alternative because it's not the case for my code. It has to be an if-statement, and I was wondering if exists something like:
if($this->_time == (('ever') OR ('day') OR ('month')))
What do you think? That would be a shorter way of the first if mentioned above
What about ?
$a1 = array("one","two","three");
$found = "two";
$notFound = "four";
if (count(array_diff($a1,array($found))) != count($a1))
/* Found */
Either you can use
$found = array("one","three");
if (count(array_diff($a1,$found)) != count($a1));
/* Either one OR three */
http://codepad.org/FvXueJkE
The only alternative I can think to accomplish this would be using regex.
$valid_times = array('ever','day','week','hour');
if(preg_match('/' . implode('|', $valid_times) . '/i', $this->_time)){
// match found
} else {
// match not found
}
[EDIT] Removed original answer since you've now specified you don't want to use switch.
In your updated question, you asked if something like this is possible:
if($this->_time == (('ever') OR ('day') OR ('month')))
The direct answer is 'no, not in PHP'. The closest you'll get is in_array(), with the array values in place in the same line of code:
if(in_array($this->_time, array('ever','day','month'))
PHP 5.4 has an update allows for shorter array syntax, which means you can drop the word array, which makes it slightly more readable:
if(in_array($this->_time, ['ever','day','month'])
But it is still an in_array() call. You can't get around that.
Sometime like this for in_array?
$arr = array(1, 2, 'test');
$myVar = 2;
function my_in_array($val, $arr){
foreach($arr as $arrVal){
if($arrVal == $val){
return true;
}
}
return false;
}
if(my_in_array($myVar, $arr)){
echo 'Found!';
}
Convoluted, but it is an alternative
$input = 'day';
$validValues = array('ever','day');
$result = array_reduce($validValues,
function($retVal,$testValue) use($input) {
return $retVal || ($testValue == $input);
},
FALSE
);
var_dump($result);
You could also use the switch statement.
switch ($this->_time) {
case 'ever':
case 'day':
//code
break;
default:
//something else
}
For the sake of science, it turns out you can use yield in a ternary operator, so you could put some complex evaluations in a anonymous generator, and have it yield on the first one that evaluates to true, without needing to evaluate them all:
$time = 'today';
if( (function()use($time){
$time == 'ever' ? yield true:null;
$time == 'today' ? yield true:null;
$time == 't'.'o'.'d'.'a'.'y' ? yield true:null;
})()->current() ){
echo 'valid';
}
In this case it will echo 'valid' without ever evaluating the concatenation.
I want to change the variable being assigned based on condition, and I can seem to get it working.
$condition = false;
($condition !== false ? $array[1][$condition] : $array[1]) = 'Test';
In this example, if $condition isn't false, I want to assign the string "Test" to $array[1][$condition]. Otherwise, assign it to $array[1]
I can easily do this like this:
if ($condition !== false) {
$array[1][$condition] = 'Test'; }
else {
$array[1] = 'Test'; }
But due to the nature of the code this can get quite cluttered, which is why I wish for it to be an inline conditional statement.
Thanks for any help!
$condition = false;
$array[1][$condition] = ($condition !== false ? 'Test' : $array[1]);
$condition !== false ? $array[1][$condition] = "Test" : $array[1] = "Test";
The result of the ternary operator is not a reference, so you can't use it as the left-hand side of an assignment.
You might be able to use variable variables and references, but this might just add complexity without providing any real benefit.
Something like this:
$a =& $array[1];
$b =& $array[1][$condition];
$var = ($condition !== false ? 'b' : 'a');
$$var = 'Test';
i have an array like this
Array ([0]=>'some values'[1]=>'')
I want to change the empty elemnt of an array to a value of 5
how can I do that
thanks
5.3 version
$arr = array_map(function($n) { return !empty($n) ? $n : 5; }, $arr);
If you know at which position it is, just do:
$array[1] = 5;
If not, loop through it and check with === for value and type equality:
foreach($array as &$element) { //get element as a reference so we can change it
if($element === '') { // check for value AND type
$element = 5;
}
}
You can use array_map for this:
function emptyToFive($value) {
return empty($value) ? 5 : $value;
}
$arr = array_map(emptyToFive, $arr);
As of PHP 5.3, you can do:
$func = function($value) {
return empty($value) ? 5 : $value;
};
$arr = array_map($func, $arr);
EDIT: If empty does not fit your requirements, you should perhaps change the condition to $value === '' as per #Felix's suggestion.
This $array[1] = 5;
I have a form that passes something like in a URL
?choice=selection+A&choice=selection+C
I'm collecting it in a form with something like (I remember that $_GET is any array)
$temp = $_GET["choice"];
print_r($temp);
I'm only getting the last instance "selection C". What am I missing
I am assuming 'choice' is some kind of multi-select or checkbox group? If so, change its name in your html to 'choice[]'. $_GET['choice'] will then be an array of the selections the user made.
If you don't intend to edit the HTML, this will allow you to do what you're looking to do; it will populate the $_REQUEST superglobal and overwrite its contents.
This assumes PHP Version 5.3, because it uses the Ternary Shortcut Operator. This can be removed.
$rawget = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : false;
$rawpost = file_get_contents('php://input') ?: false;
$target = $rawget;
$_REQUEST = array();
if ($target !== false) {
$pairs = explode('&',$rawget);
foreach($pairs as $pair) {
$p = strpos($pair,'=');
if ($p === false && !empty($pair)) {
$_REQUEST[$pair] = null;
}
elseif ($p === 0 || empty($pair)) {
continue;
}
else {
list($name, $value) = explode('=',$pair,2);
$name = preg_replace('/\[.*\]/','',urldecode($name));
$value = urldecode($value);
if (array_key_exists($name, $_REQUEST)) {
if (is_array($_REQUEST[$name])) {
$_REQUEST[$name][] = $value;
}
else {
$_REQUEST[$name] = array($_REQUEST[$name], $value);
}
}
else {
$_REQUEST[$name] = $value;
}
}
}
}
As it stands, this will only process the QueryString/GET variables; to process post as well, change the 3rd line to something like
$target = ($rawget ?: '') . '&' . ($rawpost ?: '');
All that having been said, I'd still recommend changing the HTML, but if that's not an option for whatever reason, then this should do it.