PHP using $_GET

Asked

Viewed 736 times

3

I am analyzing an example code (Tpage.class.php, from the ojetos-oriented PHP book, Link Classe), which works according to the parameters passed in the URL,

if ($_GET)//Verifica se foi passado algo junto com a URL
    //page1.php?method=listar
    //page1.php?class=Clientes&method=listar
    {
        $class = isset($_GET['class']) ? $_GET['class'] : NULL;
        //Vefirifica se foi passado uma Classe //POO
        $method = isset($_GET['method']) ? $_GET['method'] : NULL;
        //Vefirifica se foi passado um Método //Estruturado
        if ($class)
        {
            $object = $class == get_class($this) ? $this : new $class;
            if (method_exists($object, $method))
            {
                call_user_func(array($object, $method), $_GET);
            }
        }
        else if (function_exists($method))
        {
            call_user_func($method, $_GET);
        }
    }

Well, I’m having a hard time understanding what’s going on inside if and if If anyone can explain I’d be grateful.

Class that will use the top:

<?php
include_once '../app.widgets/TElement.class.php';
include_once '../app.widgets/TPage.class.php';

class mundo{
    function helloWorld($param){
        echo 'Hello ' . $param['nome'] . '<br />';
    }
}

$pagina = new TPage();
$pagina->show();

?>

Folder with all Utility Classes (Github)

  • seeing the examples in the book, and code (Github) the line: $Object = $class == get_class($this) ? $this : new $class; if it’s useless enough: $Object = new $class; (I did the test in both ways and got the same result) if anyone disagrees, share your view bridge

1 answer

11


I’ll try to explain:

if ($_GET)

Supposedly, checks if something was passed along with the URL. This test is unnecessary because $_GET is a superglobal array and I believe it is always present, regardless of variables_order contain the indicator G or not needs confirmation

Therefore it is an unnecessary condition1. The least wrong, but still unnecessary given the other conditions, would be:

if( count( $_GET ) > 0 ) {}

1. The influence of variables_order is confirmed

$class = isset($_GET['class']) ? $_GET['class'] : NULL;

It is the least possible security to do when working with querystrings: Check whether a given index (class) was informed in the URL and is present in $_GET:

http://www.domain.com/index.php?class=something

An operator is used ternary to create the variable. This operator works as follows:

$variable = ( test ? if_true : if_false );

In this case, if the GET parameter was passed by the URL, it will be present in the superglobal and this will be the variable value $class. If not present -OR- is null (feature of isset()), the NULL.

The same goes for $method, but this refers to the class method that will be invoked.

if ($class)

Checks whether the above variable was created. This test was done wrong because it only tests whether the variable was created. Regardless of the test result in the ternary the variable will be created, either with the expected value or with NULL.

Furthermore, it relies on the cast php donkey. If you learn to program like this, when and if you evolve in the language you could potentially have serious problems debugging subtle problems in your code.

A good example of this was that question.

That’s why, at all times whether to outline exactly what is being tested. In this case, using the function is_null() or typed comparison:

if( ! is_null( $class ) ) {}

Or

if( $class !== NULL ) {}

$Object = $class == get_class($this) ? $this : new $class;

Another ternary being used to define which class object will be used.

The function get_class() returns the class name of the object passed. If the argument comes from $_GET and is stored in $class is equal to the name of the current class where this code fragment is located, the pseudo-variable $this will be used indicating that the desired method ($method) shall be sought and invoked within itself or, if any, in a superclass from which it extends.

Otherwise the received value will be instantiated as if it were a different class.

Again, WRONG! The author of the code assumes that the argument coming for $_GET is an existing and localizeable class in/by the system.

Because of the second if poorly formulated and given the absence of a means of exiting the flow of others if, the elseif will not be executed because the variable $class will always exist, nullifying the possibility of that argument being considered as a function.

The least wrong, at this point in the code, would be to use class_exists() to check if it is a valid class. If it is not, the test would fail and the elseif functionary.

if (method_exists($Object, $method)) {}

The parameter being considered a class, this checks if the method coming by $_GET ($method) exists in the class, be it its own or different, instantiated.

call_user_func(array($Object, $method), $_GET);

If it exists, invoke, passing the $_GET array as argument. Again, WRONG! Because $_GET is a superglobal it doesn’t need to be injected anywhere.

The least wrong in this case, perhaps, would be to create a new array, copy $_GET and remove the entries from it class and method, because these values could hardly be necessary in the method invoked.

Else if (function_exists($method))

If the conditions had been defined correctly and that elseif could be executed, would be invoked a function known by the system.

By way of curiosity, the list of functions that could be invoked, native or defined by the programmer, can be obtained through get_defined_functions().

The difference between call_user_func() and call_user_func_array() is that in the first multiple arguments are passed in an infinite list:

call_user_func( 'funcao', $param1, $param2 /** ... */ );

And the second takes an array with N arguments:

call_user_func( 'funcao', array( $params ) );

However, as $_GET was passed and before being a superglobal it is an array, there is no difference of use between the two.

In a well-written code, call_user_func() is even accepted to create aliases of functions/methods. But it is so complicated to achieve a certain degree of flexibility that almost always the other version is more preferable.

I hope you help and, assuming that everything said in your post is true, I suggest (strictly personal opinion) that you stop reading and look for other teaching material so that you learn the right way from the start.

  • Thanks for the answer, (very well explained), a remark of mine is that the line: $Object = $class == get_class($this) ? $this : new $class; useless enough: $Object = new $class; (I tested both ways and got the same result)

  • It checks if class passed by the parameter GET is equal to the existing class. If it is, it returns itself, if it is not it creates a new object with the class passed by the string url $class

  • This type of statement is only possible to confirm if we knew the rest of the code. From what one has we can only say that this fragment is within a class, but we cannot say which and where (method).

  • Hello @Bruno Augusto, the link to this class in full this in the description of my question, the class that will be using the product class of my question I will be posting at the end of my question.

  • Okay... maybe I went through the link. u.u' Yes, it is indeed an unnecessary condition, but I would feel more comfortable knowing everything else, say, where, when and how it is sweaty Tpage and Telement because, at first glance, I think $this instead of $class would make much more sense, since one is the child of the other and $this does not distinguish between classes and superclasses.

  • Ok, I put the link to the folder on Github with the classes used.

  • Virtually unlocked the entire XD code

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.