• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 319
  • Last Modified:

Why is my ternary expression not working?

Hi I am having trouble getting ternary expression to work correctly in php:

    echo $typeEncoded;
    $table = $typeEncoded == "necklaces" ? "necklace_images"
            : $typeEncoded == "bracelets" ? "bracelet_images"
            : $typeEncoded == "earrings" ? "earring_images"
            : null;
    echo $table;

Open in new window


$typeEncoded is being echoed out as "bracelets" but $table is nothing, not even null.  What am I doing wrong?
0
FairyBusiness
Asked:
FairyBusiness
  • 4
  • 4
  • 3
  • +3
1 Solution
 
lwadwellCommented:
I works for me.  Are you sure there are no leading/trailing spaces on $typeEncoded?

echo '<pre>';
$vals = array('necklaces','bracelets','earrings','ddd','bracelets ');
foreach ( $vals as $typeEncoded ) {
    echo '-',$typeEncoded,'-', PHP_EOL;
    $table = $typeEncoded == "necklaces" ? "necklace_images"
            : $typeEncoded == "bracelets" ? "bracelet_images"
            : $typeEncoded == "earrings" ? "earring_images"
            : null;
    echo '--',$table, PHP_EOL;    
}

Open in new window

0
 
Dave BaldwinFixer of ProblemsCommented:
You're formatting it wrong or it may simply be too complicated.  See the middle of the page here: http://php.net/manual/en/language.operators.comparison.php  Did you make sure error_reporting is on on that page so you can see what the error is?  http://us3.php.net/manual/en/function.error-reporting.php
0
 
Marco GasiFreelancerCommented:
As said in Php manual, It is recommended that you avoid "stacking" ternary expressions (http://www.php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary)

I think you should use a switch statement (http://it2.php.net/manual/en/control-structures.switch.php)

switch ($typeEncoded) {
  case "necklaces": $table = "necklace_images";
  break;
  case "bracelets": $table = "bracelet_images";
  break;
  case "earrings": $table = "earrings_images";
  break;
  default: $table = null;
}

Probably it could bebetter to set $table to an empty string:

default: $table = '';

Cheers
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
Dave BaldwinFixer of ProblemsCommented:
This is what I get from @lwadwell's code so I don't think that works.

-necklaces#--earring_images
-bracelets#--earring_images
-earrings#--earring_images
-ddd#--
-bracelets #--
0
 
lwadwellCommented:
must be too early in the morning for me ... yup ... it kept repeating the first true.
This works now ... but please listen to the others and rewrite.
foreach ( $vals as $typeEncoded ) {
    echo '-',$typeEncoded,'-', PHP_EOL;
    $table = $typeEncoded == "necklaces" ? "necklace_images"
            : ( $typeEncoded == "bracelets" ? "bracelet_images"
            : ($typeEncoded == "earrings" ? "earring_images"
            : null));
    echo '--',$table, PHP_EOL;
}

Open in new window

0
 
FairyBusinessAuthor Commented:
Geez I turned it into a switch statement but $table still is nothing!

    switch ($typeEncoded) {
    case "necklaces": 
        $table = "necklace_images";
        break;
    case "bracelets": 
        $table = "bracelet_images";
        break;
    case "earrings": 
        $table = "earrings_images";
        break;
    default: 
        $table = null;
    }
    echo $table;

Open in new window


Yet $typeEncoded is "bracelets" everytime before the switch even begins.... I have the error reporting turned on but no errors :(
0
 
FairyBusinessAuthor Commented:
I tried this however and it works:

    switch ("bracelets") {
    case "necklaces": 
        $table = "necklace_images";
        break;
    case "bracelets": 
        $table = "bracelet_images";
        break;
    case "earrings": 
        $table = "earrings_images";
        break;
    default: 
        $table = null;
    }
    echo $table;

Open in new window


$type is bracelets with no quotes (the var being passed into the function) so I did this to it:

$typeEncoded = json_encode($type);

Open in new window


I guess that is not a good way to add quotes around it??
0
 
lwadwellCommented:
It possibly isn't a good way to add quotes.  Which leads me to the question ... why do you want to add quotes?  By adding the quotes you are effectively doing is adding quotes onto the the end and then trying to compare to strings without the quotes.  So, using single quotes to 'quote the string' instead, you are comparing '"bracelets"' with 'bracelets' ... it is the double quotes that makes them different.
0
 
Dave BaldwinFixer of ProblemsCommented:
Look at this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>PHP Ternary</title>
</head>
<body>
<h1>PHP Ternary</h1>
<?php 
echo '<pre>';
$vals = array('necklaces','bracelets','earrings','ddd','bracelets ');
foreach ( $vals as $typeEncoded ) {
    echo '-',$typeEncoded,'#';
switch ($typeEncoded) {
    case "necklaces": 
        $table = "necklace_images";
        break;
    case "bracelets": 
        $table = "bracelet_images";
        break;
    case "earrings": 
        $table = "earrings_images";
        break;
    default: 
        $table = null;
    }
    echo '--',$table, PHP_EOL;    
}
?>
</body>
</html>

Open in new window

0
 
lwadwellCommented:
The output I get:
-necklaces#--necklace_images
-bracelets#--bracelet_images
-earrings#--earrings_images
-ddd#--
-bracelets #--

Open in new window

Were you expecting a different result?
0
 
Dave BaldwinFixer of ProblemsCommented:
No, that's right.  The second 'bracelets ' has a space in the string so it is not an exact match.  It's from your code above.
0
 
Julian HansenCommented:
I think your problem in your initial post is you need to put some brackets around the expressions as shown below
<?php
	$typeEncoded = 'necklaces';
	$typeEncoded = 'bracelets';
    echo $typeEncoded;
    $table = $typeEncoded == "necklaces" ? "necklace_images"
            : ($typeEncoded == "bracelets" ? "bracelet_images"
            : ($typeEncoded == "earrings" ? "earring_images"
            : null));
    echo $table;
?>

Open in new window

0
 
Ray PaseurCommented:
$table is nothing, not even null
but $table still is nothing!
I haven't had time to read the rest of the comments, but stacked ternary operators are like multiple inheritance or trying to trim your hedge with a lawn mower held up in the air.  Just don't do that!

If you do not know what is in a variable, use var_dump() to print out the contents of the variable.  If you see anything in the var_dump() output that is counterintuitive, use the browser's view source to look at the output.  Check the length of the data; it may contain leading or trailing blanks, or multi-byte characters.

You can and should normalize external data with trim() and perhaps strtoupper() so you know exactly what your script would test for.  In the instant case, I would apply both of those functions and I would use switch/case instead of the awkward and error-prone stacked ternary operators.

Here is my take on it.  The resulting array will have predictable keys in any case that includes an associated image directory, and any element of the array that is null, indicates an unusable input.  Another way to handle this (and a way that is more extensible) would include array_intersect_key().
http://www.laprbass.com/RAY_temp_fairybusiness.php

<?php // RAY_temp_fairybusiness.php
error_reporting(E_ALL);
echo '<pre>';

// AN ARRAY OF STRINGS
$vals
= array
( 'necklaces'
, 'bracelets'
, 'earrings'
, 'ddd'
, 'bracelets ' // NOTE THAT THIS WILL NORMALIZE TO 'BRACELETS'
)
;

// USE AN ITERATOR TO PROCESS EACH ELEMENT OF THE ARRAY
foreach ($vals as $val)
{
    // NORMALIZE THE INPUT
    $val = trim(strtoupper($val));

    // CHOOSE THE APPROPRIATE IMAGE SET
    switch ($val)
    {
        case "NECKLACES" : $table[$val] = "necklace_images"; break;
        case "BRACELETS" : $table[$val] = "bracelet_images"; break;
        case "EARRINGS"  : $table[$val] = "earrings_images"; break;
        default          : $table[$val] = NULL;
    }
}

// SHOW THE WORK PRODUCT
var_dump($table);

Open in new window

0
 
FairyBusinessAuthor Commented:
I stopped json.encoding the $type and switched the quotes in my switch statement to single quotes and it worked.  I was trying to add double quotes around the $type with json.encode bc I double quotes in my switch statement and I was afraid they would not evaluate right.  Sorry for the headache I caused everyone.
0
 
Ray PaseurCommented:
No headache at all -- but please learn about var_dump().  The only thing that computer programs do is transform one representation of data into another representation.  Being able to see the data helps you accomplish these transformations correctly and efficiently.

best regards, ~Ray
0

Featured Post

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 4
  • 4
  • 3
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now