Mensagem de erro Padrões estritos: o método não estático não deve ser chamado estaticamente no php

114

Eu tenho o seguinte php. No entanto, quando vejo o index.php, recebo a seguinte mensagem de erro.

Padrões rígidos: o método não estático Page :: getInstanceByName () não deve ser chamado estaticamente em /var/www/webworks/index.php na linha 12

Espero que alguém possa me dizer como resolver o problema.

index.php

// { common variables and functions
include_once('ww.incs/common.php');
$page=isset($_REQUEST['page'])?$_REQUEST['page']:'';
$id=isset($_REQUEST['id'])?(int)$_REQUEST['id']:0;
...

// { get current page id
if(!$id){
    if($page){ // load by name
        $r=Page::getInstanceByName($page);
        if($r && isset($r->id))$id=$r->id;
    }
    if(!$id){ // else load by special
        $special=1;
        if(!$page){
            $r=Page::getInstanceBySpecial($special);
            if($r && isset($r->id))$id=$r->id;
        }
    }
}

// { load page data
if($id){
    $PAGEDATA=(isset($r) && $r)?$r : Page::getInstance($id);
}
else{
    echo '404 thing goes here';
    exit;
}
...
...

ww.incs / common.php

<?php
require dirname(__FILE__).'/basics.php';
...
...

ww.incs / basics.php

session_start();
if(!function_exists('__autoload')){
    function __autoload($name) {
        require $name . '.php';
    }
}
...
...

Page.php

class Page{
    static $instances             = array();
    static $instancesByName     = array();
    static $instancesBySpecial   = array();
    function __construct($v,$byField=0,$fromRow=0,$pvq=0){
        # byField: 0=ID; 1=Name; 3=special
        if (!$byField && is_numeric($v)){ // by ID
            $r=$fromRow?$fromRow:($v?dbRow("select * from pages where id=$v limit 1"):array());
        }
        else if ($byField == 1){ // by name
            $name=strtolower(str_replace('-','_',$v));
            $fname='page_by_name_'.md5($name);
            $r=dbRow("select * from pages where name like '".addslashes($name)."' limit 1");
        }
        else if ($byField == 3 && is_numeric($v)){ // by special
            $fname='page_by_special_'.$v;
            $r=dbRow("select * from pages where special&$v limit 1");
        }
        else return false;
        if(!count($r || !is_array($r)))return false;
        if(!isset($r['id']))$r['id']=0;
        if(!isset($r['type']))$r['type']=0;
        if(!isset($r['special']))$r['special']=0;
        if(!isset($r['name']))$r['name']='NO NAME SUPPLIED';
        foreach ($r as $k=>$v) $this->{$k}=$v;
        $this->urlname=$r['name'];
        $this->dbVals=$r;
        self::$instances[$this->id] =& $this;
        self::$instancesByName[preg_replace('/[^a-z0-9]/','-',strtolower($this->urlname))] =& $this;
        self::$instancesBySpecial[$this->special] =& $this;
        if(!$this->vars)$this->vars='{}';
        $this->vars=json_decode($this->vars);
    }
    function getInstance($id=0,$fromRow=false,$pvq=false){
        if (!is_numeric($id)) return false;
        if (!@array_key_exists($id,self::$instances)) self::$instances[$id]=new Page($id,0,$fromRow,$pvq);
        return self::$instances[$id];
    }
    function getInstanceByName($name=''){
        $name=strtolower($name);
        $nameIndex=preg_replace('#[^a-z0-9/]#','-',$name);
        if(@array_key_exists($nameIndex,self::$instancesByName))return self::$instancesByName[$nameIndex];
        self::$instancesByName[$nameIndex]=new Page($name,1);
        return self::$instancesByName[$nameIndex];
    }
    function getInstanceBySpecial($sp=0){
        if (!is_numeric($sp)) return false;
        if (!@array_key_exists($sp,$instancesBySpecial)) $instancesBySpecial[$sp]=new Page($sp,3);
        return $instancesBySpecial[$sp];
    }
canela
fonte
15
Hmm, pode ser que você esteja chamando um método estaticamente e esse método não está definido como estático? Você sabe, quase exatamente o que o erro diz, no número da linha diz ...
Harold1983-

Respostas:

189

Seus métodos estão sem a palavra - staticchave . mudança

function getInstanceByName($name=''){

para

public static function getInstanceByName($name=''){

se você quiser chamá-los estaticamente.

Observe que os métodos estáticos (e Singletons ) são morte para testabilidade .

Observe também que você está trabalhando demais no construtor, especialmente todas as consultas que não deveriam estar lá. Tudo o que o seu construtor deve fazer é definir o objeto em um estado válido. Se você precisa de dados de fora da classe para fazer isso, considere injetá-los em vez de extraí-los. Observe também que os construtores não podem retornar nada. Eles sempre retornarão vazios, então todas essas return falsedeclarações não fazem nada além de encerrar a construção.

Gordon
fonte
2
Os códigos são deste livro ... packtpub.com/cms-design-using-php-and-jquery/book . Acho que você deveria escrever um livro, Gordon. :-)
shin
5
@shin Nah, eu só repetiria o que os outros disseram melhor do que eu antes. Mas isso é um código realmente ruim para um livro que foi lançado em dezembro de 2010. Eles dão algum motivo para omitir qualquer palavra-chave de visibilidade ou não seguir a convenção de codificação PEAR? Esperemos que a arquitetura jQuery e CMS geral seja mais sólida.
Gordon
17
@dzona isso seria ignorar os problemas com o código, não consertá-lo.
Gordon
1
NOTA importante: a publicpalavra-chave é usada apenas em declarações de função / variável de dentro de uma classe. Consulte stackoverflow.com/questions/13341378/…
cssyphus
1
@Gordon, só por curiosidade - por que você defende mudar o método ofensivo para static, em vez de (re) escrever o código a ser usado $p = new Page(); $p->getInstanceByName();?
Dennis
21

Acho que isso pode responder à sua pergunta.

Método não estático ... não deve ser chamado estaticamente

Se o método não for estático, você precisa inicializá-lo assim:

$var = new ClassName();
$var->method();

Ou, no PHP 5.4+, você pode usar esta sintaxe:

(new ClassName)->method();
Ervilha
fonte
Is (new ClassName) -> method (); compatível com PHP 5.3 também?
Jeff,
1
@Jeff, eu usaria (new ClassName())->method();e acredito que seja compatível com PHP de 5 a 7
Dennis
1
(new ClassName)->method();não é compatível com PHP 5.3. Eu apenas tentei.
Sonny
1

Experimente isto:

$r = Page()->getInstanceByName($page);

Funcionou para mim em um caso semelhante.

Andrés Frías
fonte
1

use className-> function (); em vez disso className :: function ();

ulas korpe
fonte
0

return falsenormalmente destina-se a encerrar a criação do objeto com uma falha. É tão simples quanto isso.

Tomas
fonte
0

Se a resolução de escopo: tiver que ser usada fora da classe, a respectiva função ou variável deve ser declarada como estática

class Foo { 
        //Static variable 
        public static $static_var = 'static variable'; 
        //Static function 
        static function staticValue() { return 'static function'; } 

        //function 
        function Value() { return 'Object'; } 
} 



 echo Foo::$static_var . "<br/>"; echo Foo::staticValue(). "<br/>"; $foo = new Foo(); echo $foo->Value();
Ravi Krishnan
fonte
1
Você pode fornecer exemplos para o OP e todos os futuros visitantes?
B001 ᛦ
<? php class Foo {/ * Variável estática * / public static $ static_var = 'variável estática'; / * Função estática * / função estática staticValue () {retornar 'função estática'; } / * função * / função Valor () {retornar 'Objeto'; }} echo Foo :: $ static_var. "<br/>"; echo Foo :: staticValue (). "<br/>"; $ foo = novo Foo (); echo $ foo-> Value (); / * Espero que este exemplo o ajude * /
Ravi Krishnan
-1

Em vez de usar a instância com o operador de resolução de escopo :: porque não foi definida como uma função estática.

$r=Page::getInstanceByName($page);

mude para:

$r=Page->getInstanceByName($page);

E vai funcionar como um encanto.

Lorand
fonte