php 7 strict error op extensie classe met zelfde functie naam

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Johan K

Johan K

22/09/2015 05:16:22
Quote Anchor link
Ik was even aan het kijken hoe PHP 7 werkt op het huidige systeem wat ik aan het schrijven en alles werkt behalve dat ik een strict error krijg in mijn database classe.

Ik maak gebruik van een classe die PDO extend, en hang hieraan een custom PDOStatement class.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
 class Statement extends PDOStatement{
  public function execute(...$args){
    parent::execute();
  }
 }

 class Database extends PDO{}
?>


De foutmelding hierop is:
Warning: Declaration of Statement::execute(...$args) should be compatible with PDOStatement::execute($bound_input_params = NULL) in /path/to/statement.php on line 90

Hoewel ik de foutmelding begrijp, en de error heb weggewerkt met:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
    public function execute($a = null, ...$args){
      array_unshift($args, $a);
      $i = 0;
      
      foreach($args as $var){
        if(is_array($var)){
          foreach($var as $key => $val){
            if(preg_match('/(.*)(:.*)/', $key, $matches)){
              $this->bindValue($matches[2], $val, empty($matches[1]) ? PDO::PARAM_STR : $this->getParam($matches[1][0]));
            }
else {
              throw new DatabaseException("Unsupported array index, expected a :named parameter.", self::EX_PARAM_MISMATCH);
            }
          }
        }
else {
          $this->bindValue($i+1, $args[$i++]);
        }
      }


      $this->dbh->rsl = parent::execute();
      $this->dbh->sth = $this;

      return $this;
    }

?>

Deze fix is natuurlijk niet echt netjes, maar ik begrijp niet echt waar deze melding vandaan komt en of dit misschien wel eens een bug zou kunnen zijn aangezien het lijn nummer ook niet klopt.

Hoewel het probleem uiteindelijk door de functie naam komt, wilde ik hier alleen een andere gebruik methode aan vast makken zodat je in de code niet de hele tijd met array's hoeft te werken.

In PHP 6 had ik hier geen problemen aan, en strict error reporting stond ook aan.
Dit probleem had ik volgens mij niet in PHP 7 RC1 (draai nu op RC2).
Gewijzigd op 22/09/2015 05:17:54 door Johan K
 
PHP hulp

PHP hulp

22/12/2024 19:33:45
 
DavY -

DavY -

22/09/2015 08:00:37
Quote Anchor link
Ik heb zelf php7 nog niet, maar heb er wel wat over gelezen, dus wat als je het zo doet:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
public function execute(): array {
    parent::execute();
}

?>
 
Ward van der Put
Moderator

Ward van der Put

22/09/2015 09:25:10
Quote Anchor link
Waarom doe je dit?

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
    public function execute(...$args)
    {

        parent::execute();
    }

?>


Als een methode niets anders doet dan dezelfde methode van de parent aanroepen, dan kun je de methode namelijk beter weglaten.
 
Johan K

Johan K

22/09/2015 16:34:22
Quote Anchor link
DavY Blaat op 22/09/2015 08:00:37:
Ik heb zelf php7 nog niet, maar heb er wel wat over gelezen, dus wat als je het zo doet:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
public function execute(): array {
    parent::execute();
}

?>

Dat is optioneel, hoeft niet.

Ward van der Put op 22/09/2015 09:25:10:
Waarom doe je dit?

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
    public function execute(...$args)
    {

        parent::execute();
    }

?>


Als een methode niets anders doet dan dezelfde methode van de parent aanroepen, dan kun je de methode namelijk beter weglaten.

Dat is niet de code die ik gebruik, dit is een voorbeeld van de stuctuur van mijn classe en ook meteen de code die de foutmelding geeft zonder poespas.

De daadwerkelijke "execute" methode die ik gebruik is in het tweede stukje code met de "quick" fix.
Gewijzigd op 22/09/2015 16:35:06 door Johan K
 
Thomas van den Heuvel

Thomas van den Heuvel

22/09/2015 17:16:58
Quote Anchor link
Quote:
Warning: Declaration of Statement::execute(...$args) should be compatible with PDOStatement::execute($bound_input_params = NULL) in /path/to/statement.php on line 90

Dat geeft precies aan wat er aan scheelt? Jouw spinoff is niet compatibel.

In de execute() van PDOStatement is de parameter $bound_input_params optioneel, in jouw variant is deze verplicht.

Ik ken de syntax "...$args" niet, maar als je er nu eens het volgende van maakt?
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
class Statement extends PDOStatement {
    public function execute($args=NULL) {
        parent::execute($args);
    }
}

?>
 
Johan K

Johan K

22/09/2015 18:01:47
Quote Anchor link
The syntax ...$args zit ook in PHP 6, en werkt fantastisch aangezien je ook niet meer met func_get_args() hoeft te werken.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
 function bar($...foo){
  foreach($foo as $var){
   echo $var;
  }
 }


 foo('dit','is','een','voorbeeld'); // result: ditiseenvoorbeeld
 foo(...['dit','is','array unpacking']); // result: ditisarray unpacking | hoewel dit natuurlijk niet logisch is, is het wel bruikbaar als foo() argumenten moet hebben.
?>


Jouw voorbeeld doet eigenlijk hetzelfde als wat de "execute" function vraagt, dus dit zal werken maar het verslaat een beetje het doel van de functie in mijn voorbeeld.

Een voorbeeld hoe de DB gebruikt word:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
echo $this->db->prepare("select id where email = ? and password = ?")->execute($email, $password)->fetchField('id');
echo $this->db->prepare("select iets where a = ? and b = ?" and c = ?)->execute($a, $b, $c)->executed();
?>


Execute heeft dus variable argumenten lengte, naartuurlijk kan je met func_get_args() werken, omdaar weer omheen te loopen maar dit is mooier, minder code en mogelijk tot nu :s (zonder problemen)
 
Wouter J

Wouter J

22/09/2015 18:13:21
Quote Anchor link
Je argumenten moeten hetzelfde zijn als in parent class. PDO::execute() gebruikt geen variadic arguments, dus mag die in jouw class dat ook niet doen.
 
Johan K

Johan K

22/09/2015 18:16:37
Quote Anchor link
Wouter J op 22/09/2015 18:13:21:
Je argumenten moeten hetzelfde zijn als in parent class. PDO::execute() gebruikt geen variadic arguments, dus mag die in jouw class dat ook niet doen.

Dit is dus nieuw in PHP 7?
 
Wouter J

Wouter J

22/09/2015 19:37:19
Quote Anchor link
Nee, PHP gooit altijd al errors als je argumenten niet overeen komen met die in de parent class (behalve bij de constructor).
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.