how to pass an array with N arguments to a bind_param within a class?

Asked

Viewed 274 times

1

I’m trying to develop a global class for pagination

Follow the code:

class Pager {
private $Sql;
private $Limit;
private $ArgType;
private $Page;
private $Arguments;
private $ArgNumber;
private $Connect;
private $result=array();
public function setSql($Sql){
    $this->Sql=$Sql;
    return false;
}
public function setLimit($Limit){
    $this->Limit=$Limit;
    return false;
}
public function setArguments(){
    $this->Arguments=func_get_args();
    $this->ArgNumber=func_num_args();
    return false;
}
public function setArgType($ArgType){
    $this->ArgType=$ArgType;
    return false;
}
public function setConnect($Connect){
    $this->Connect=$Connect;
    return false;
}
public function setPage($Page){
    $this->Page= isset($Page)?$Page:1;
    return false;
}
private function countRegister(){
    $Pager = $this->Connect->prepare($this->Sql);
    switch ($this->ArgNumber){
        case 1:
            $Pager->bind_param($this->ArgType,$this->Arguments[0]);
        break;
        case 2:
            $Pager->bind_param($this->ArgType,$this->Arguments[0],$this->Arguments[1]);
        break;
        case 3:
            $Pager->bind_param($this->ArgType,$this->Arguments[0],$this->Arguments[1],$this->Arguments[2]);
        break;
        case 4:
            $Pager->bind_param($this->ArgType,$this->Arguments[0],$this->Arguments[1],$this->Arguments[2],$this->Arguments[3]);
        break;
        case 5:
            $Pager->bind_param($this->ArgType,$this->Arguments[0],$this->Arguments[1],$this->Arguments[2],$this->Arguments[3],$this->Arguments[4]);
        break;
    }
    $Pager->execute();
    $Pager->store_result();
    return $Pager->num_rows;
    $Pager->close();
}
private function countPages($NumReg){
    return ceil($NumReg/$this->Limit);
}
private function prevPage(){
    if($this->Page>1)
        return $this->Page-1;
    else
        return false;
}
private function nextPage(){
    if($this->Page<$this->result['Pages'])
        return $this->Page+1;
    else
        return false;
}
private function getStart(){
    return ($this->Page-1)*$this->Limit;
}
public function execPager(){
    $this->result['Pages'] = $this->countPages($this->countRegister());
    $this->result['PrevPage'] = $this->prevPage();
    $this->result['NextPage'] = $this->nextPage();
    $this->result['Start'] = $this->getStart();
    $this->result['Limit'] = $this->Limit;
    return false;
}
public function getPager(){
    return $this->result;
}

}

But in the private function execPage() I don’t see a way to do the bind_param with the array who picked up the function setArguments the only way was using a case with predefined possibilities

Any suggestions on how to pass these parameters to the function and be able to perform in this way?

I am using mysqli and the class is in early stage in function setArgument I’ll pass N arguments and put the argument type by the function setArgType and the same will be a string then I’ll put it inside the bind_param thus

$Pager->bind_param($this->setArgType, [Todos os N argumentos da setArguments]);
  • Cade the bind_param() get’s(sql, limit, connect) should not return something instead of assigning?

  • actually the name is contrary to the use, I’m doing it a little bit hasty today, but the intention is to assign values, as the goal is to leave working first to improve after I didn’t stop to think about the correct name of the variables

  • I’ll upgrade to set

  • 1

    now you’ve become more understanding

1 answer

2


I won’t go into the merit of responsibility of objects because that is not the purpose of the question but what you have implemented does not make sense.

Your class has none Setter, public method for which data can be defined for the working class. The closest one would be the getArguments() that hints that something will be returned and not definite.

In addition to all the various changes you will need to make this class plausible to use would be something like this:

class Paginador {

    // ...

    private $arguments = array();

    public function setArguments( $argument, $value ) {

        $this -> arguments[ $argument ] = $value;
    }

    public function getAruments() {
        return $this -> arguments;
    }

    // ...
}

Once this is done, your class can already be manipulated externally through the object instance.

Now, as to the scope of the question.

First you have to define where this bind_param will come. Are you from an outside class? From a native class?

Assuming your answer is PDO you must first prepare the statement, that is, the SQL string and itself, defining the proper ones placehodlers, are named (preceded by colons) or indexed (questions only) and, in their method execPage() you iterate the arguments of your argument property and with each iteration you link the new argument:

class Paginador {

    // ...

    private function execPage() {

        // Prepare statement

        foreach( $this -> arguments as $argument => $value ) {

            if( is_string( $value ) && ! is_numeric( $value ) ) {

                $dataType = PDO::PARAM_STR;

            } else {

                $dataType = PDO::PARAM_INT;
            }

            $stmt -> bindParam( $argument, $value, $dataType );
        }
    }

    // ...
}

The didactic example above assumes that the statement prepared be in the variable $stmt

That’s basically it, but you REALLY need to study Object Orientation better because just throwing ideas into a class is not OOP.

A tip: Avoid func_get_args() whenever possible. This function should only be used when you REALLY don’t know how many arguments will be told for a given function / method And there is no other better way to do it.

in this scenario, the best way to do it would be to inform an array with key/value pairs or use Fluent Interfaces.

  • That one bind_param looks like a mysqli.

  • Big chance, I only mentioned the PDO because I never messed with Mysqli

  • edited the post, I saw that the form I wrote was really confused and now I believe it is more understandable, I did not see a better way to pass the arguments beyond func_get_args() since they can have N arguments in this function

  • 1

    When I answered I tried to cover even a future edition then, so, what was said is still valid and remains my advice to you to study better Object Orientation and the principles stemming from it. You will see that, for example, database-related tasks should not be within the pagination class, but in another class, apart, and the object of that class would be injected into the Pagination class.

  • Even so I do not see a way to make bind_param in mysqli, I see that in PDO is possible, but the same has not applied to mysqli

  • It’s basically the same thing. Mysqli also has an "object-oriented" approach Ali in the second code just that the variable $stmt is the return of a successful Mysqli::prepare().

  • @Brunoaugusto edited the question with the code I just got... and bind_param PDO can be done online while mysqli does not, I have to put all the items in one line

  • If you check the Mysqli documentation you can see that must pass a variable (second argument) and also can pass two, three, four... in the following arguments. By the description of the manual gives to understand that what you inform to $types will be applied to all variables. This is wrong as it can make a double be treated as a int. Therefore, it is more interesting to do as in foreach response, but using the corresponding function instead of PDO.

Show 3 more comments

Browser other questions tagged

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