错误消息严格的标准:非静态方法不应在php中静态调用


114

我有以下php。但是,当我看到index.php时,出现以下错误消息。

严格的标准:非静态方法Page :: getInstanceByName()不应在第12行的/var/www/webworks/index.php中静态调用

我希望有人可以告诉我如何解决该问题。

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];
    }

15
嗯,可能是您在静态地调用方法,而该方法未定义为静态方法吗?您几乎知道错误的确切含义,即错误所在的行号……
Harold1983-2011年

Answers:


189

您的方法缺少static关键字。更改

function getInstanceByName($name=''){

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

如果要静态调用它们。

请注意,静态方法(和Singletons)是可测试性的牺牲品

还要注意,您在构造函数中做的工作太多了,尤其是所有查询都不应放在其中。您的构造函数应该做的就是将对象设置为有效状态。如果您必须从类外部获取数据,请考虑注入数据而不是提取数据。另请注意,构造函数无法返回任何内容。它们将始终返回void,因此所有这些return false语句都只会终止构造。


2
代码来自这本书... packtpub.com/cms-design-using-php-and-jquery/book。我认为您应该写一本书,戈登。:-)
shin

5
@shin Nah,我只想重复别人说的比我好。但这对于2010年12月发行的书来说确实是非常糟糕的代码。它们是否提供任何理由省略任何可见性关键字或不遵循PEAR编码约定?让我们希望jQuery和常规CMS体系结构更加牢固。
Gordon

17
@dzona会忽略代码的问题,而不是对其进行修复。
Gordon

1
重要说明:public关键字仅在类中的函数/变量声明中使用。参见stackoverflow.com/questions/13341378/…–
cssyphus

1
@戈登,很好奇-为什么您主张将有问题的方法更改为static,而不是(重新)编写要使用的代码$p = new Page(); $p->getInstanceByName();
丹尼斯

21

我认为这可以回答您的问题。

非静态方法.....不应静态调用

如果该方法不是静态的,则需要像这样进行初始化:

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

或者,在PHP 5.4+中,您可以使用以下语法:

(new ClassName)->method();

是(新的ClassName)-> method(); 与PHP 5.3兼容吗?
杰夫

1
@Jeff,我会用 (new ClassName())->method();,并且我相信它与PHP兼容(从5到7)
Dennis

1
(new ClassName)->method();与PHP 5.3不兼容。我刚试过
桑尼



0

return false通常是指以失败终止对象创建。它是如此简单。


0

如果必须在类外使用范围解析:::则应将相应的函数或变量声明为static

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();

1
您能为OP和所有未来的访客提供示例吗?
B001ᛦ16年

<?php class Foo {/ *静态变量* / public static $ static_var ='静态变量'; / *静态函数* /静态函数staticValue(){返回“静态函数”;} / * function * / function Value(){return'Object'; 回声Foo :: $ static_var。“ <br/>”; 回声Foo :: staticValue()“ <br/>”; $ foo =新的Foo(); echo $ foo-> Value(); / *希望此示例对您有帮助* /
Ravi Krishnan

-1

而不是将实例与范围解析运算符::一起使用,因为它不是像静态函数那样定义的。

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

更改为:

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

它会像魅力一样工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.