PHP - ¿Por qué "Index.php? Action =" no se reconoce como "Index.php?"

Todos,

I'm building a front controller in PHP. In it, I say:

if (isset($_GET['action'])){
        $action=$_GET['action'];
    } else {
        $action='';
    }

I follow that with a switch statement than governs which controller is called based on the value of $action:

switch ($action){
        case '':
            require_once('Controller_Welcome.php');
            $command=new controller_Welcome();
            break;
        case 'logon':
            require_once('Controller_Logon.php');
            $command=new controller_Logon();
            break;
        default:
            require_once('Controller_Unknown.php');
            $command=new controller_Unknown();
            break;
    }
$command->execute();

This works fine. When I launch the app, the URL is http://.../Index.php? y el Controller_Welcome.php is called. If I click on the logon menu entry, I get http://.../Index.php?action=logon, y el Controller_Logon.php is called. If I manually edit the URL to set ...?action=... to some unknown value, I get Controller_Unknown.php, which is my error page. So all is well.

What I don't understand is that if I manually alter the url to show http://.../Index.php?action=, I get the error page rather than the welcome page. Why is it that php doesn't associate a url ending with ...?action= with the switch case $action='';?

(There's no logical user case when that would happen, but I still don't understand it...)

Gracias,

JDelage

PS: Var_dumping $action devoluciones string(0) "".

preguntado el 28 de agosto de 11 a las 04:08

var_dump($action); returns what? -

Try var_dumping your variable, maybe it's not what you think it is. -

don't see why welcome does not work, add an exit('') on this page for each statement instead of calling the controller in case there is an issue there -

5 Respuestas

Just a note that may help with readability, and further development efforts. It appears your naming convention could permit a bit more "magia", giving way for a sort of convention over configuration, and avoidance of code duplication:

define('PATH_CONTROLLERS', 'path/to/controllers/');

$action = !empty($_GET['action'])
    ? $_GET['action']
    : 'default';

switch($action){
    case 'default':
    case 'welcome':
    case 'authenticate':
        $controller_name = "controller_{$action}";
        break;
    default:
        $controller_name = 'controller_404';
        break;
}

require PATH_CONTROLLERS . "{$controller_name}.php";
$controller = new $controller_name();

$controller->execute();

Dado:

// index.php

$action:          'default'
$controller_name: 'controller_default'
require():        'path/to/controllers/controller_default.php'

// index.php?action=authenticate

$action:          'authenticate'
$controller_name: 'controller_authenticate'
require():        'path/to/controllers/controller_authenticate.php'

// index.php?action=foobar

$action:          'foobar'
$controller_name: 'controller_404'
require():        'path/to/controllers/controller_404.php'

Respondido el 06 de junio de 14 a las 18:06

@Col. Shrapnel - Anidado ternary operators would issue a parse error if I had my way, but are you suggesting this is in fact menos ¿legible? - Dan Lugg

I am talking not of parse errors but of readability. if statement can always be read as plain English while ternary is barbarian. $action = !empty($_GET['action'] my foot! most deceiving code one may writ - Tu sentido común

Haha @Col. Shrapnel - My mention of parse errors was only because anidado ternary operators are so unreadable, they debemos in fact issue one, inhibiting coders from considering them an option. Circumstances like this however, I feel benefit from the brevity afforded by them. Six of one, really; any savvy programmer will (debemos) read them the same way. - Dan Lugg

Cuando configuras ?action=, obtendrás un null valor de retorno para $_GET['action']. So in your scenario, the switch statement will use the default case. Like everyone said, you can always use var_dump to see the return value.

Respondido 28 ago 11, 08:08

1) GET and POST values can never be null, at worst they're an empty string! 2) null == '' - deceze ♦

switch doesn't do type checking, it's the equivalent of if (null == '') {...} which evalutes to true in a regular non-typed comparison in php. - Marc B

I think action is not what you think it is. This works as expected for me.

for url ending in 'action=' blank is echoed
for url ending in 'action=anything' anything is echoed


    var_dump($_GET);
    $action = $_GET['action'];

switch ($action){
        case '':
            echo "blank";
            break;
        default:
            echo $action;
            break;
    }

Respondido 28 ago 11, 08:08

Saw your latest comment about dumping the var. I copied your code in verbatim and your switch statement works fine for me. Is there any way your Controller_Welcome is somehow erroring and then redirecting to the Controller_Unknown? - mrtsherman

The behavior you describe cannot be reproduced. I used the following and the results do no demonstrate what you are describing:

<pre>
<?php

if (isset($_GET['action'])){
    $action=$_GET['action'];
} else {
    $action='';
}

var_dump($action);
echo "\n";
var_dump($_GET);
echo "\n";


switch ($action){
    case '':
        die('empty action</pre>');
    case 'logon':
        die('logon action</pre>');
    default:
        die('unknown action</pre>');
    }
?>

llamada:

http://host.com/test.php?action=

resultado:

string(0) ""

array(1) {
  ["action"]=>
  string(0) ""
}

empty action

Respondido 28 ago 11, 18:08

you're a bit late with your answer - Tu sentido común

Reading the answers (and their times) I see what you mean ;) - Majid Fouladpour

There is something with your other code.
this one works fine and throws Controller_Welcome at empty action

Respondido 28 ago 11, 09:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.