Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/239.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP5,带有static/private、$this和self:的类和变量/方法作用域:_Php_Class_Scope - Fatal编程技术网

PHP5,带有static/private、$this和self:的类和变量/方法作用域:

PHP5,带有static/private、$this和self:的类和变量/方法作用域:,php,class,scope,Php,Class,Scope,我有这个: class Database{ private $name = ''; private $user = ''; private $password = ''; private $host = 'localhost'; private $prefix = ''; private $connection_handle = null; private function Connect(){ $th

我有这个:

class Database{    
    private $name = '';
    private $user = '';
    private $password = '';   
    private $host = 'localhost';
    private $prefix = '';   
    private $connection_handle = null;

    private function Connect(){
        $this->connection_handle = mysql_connect($this->host, $this->user, $this->password); 

        if( !$this->connection_handle ){
            die( 'Could not connect: ' . mysql_error() );
        }else{
            mysql_select_db( $this->name, $this->connection_handle );
        }
    }

    private function Close(){
        mysql_close( $this->connection_handle );
    } 

    public static function Query( $query ){
        $this->Connect();   
            $result = mysql_query( $query, $this->connection_handle );
            if( !$result ){
                die( 'Error: ' . mysql_error() );
            }else{
                $DatabaseQuery = new DatabaseQuery();
                    $DatabaseQuery->result = $result;       
                    $DatabaseQuery->mysql_num_rows = mysql_num_rows($result);

                return $DatabaseQuery;
            }
        $this->Close();
    } 
}
我将查询设置为静态的,因为它的调用类似于“Database::Query” 其他函数不需要被任何其他类访问,所以我将它们设置为私有

从查询函数访问Connect函数时出现此错误

“不在对象上下文中时使用$this”

考虑到private使这些变量对这个类是私有的,但对其中的所有方法都是可用的,所以我在获取函数的范围方面遇到了问题

我可以做self::Connect(),但我对它的理解还不足以保证它的使用

你能解释一下self::和%this->之间的区别吗

我也不能访问我的私有变量,它们真的不需要在这个类之外访问,我再次将它们设置为私有,因为。。。然而$this->connection\u句柄对变量没有作用域

我真的需要把它们都公开吗?必须有一种方法使它们仅可用于该类及其扩展

编辑://

我最终使所有变量都成为私有静态变量。 这是一种可以接受的方式吗

编辑://

我现在得到了以下代码:

class Database{    
    private static $name = '';
    private static $user = '';
    private static $password = '';   
    private static $host = 'localhost';
    private static $prefix = '';   
    private static $connection_handle = null;

    private static function Connect(){
        self::$connection_handle = mysql_connect(self::$host, self::$user, self::$password); 

        if( !self::$connection_handle ){
            die( 'Could not connect: ' . mysql_error() );
        }else{
            mysql_select_db( self::$name, self::$connection_handle );
        }
    }

    private static function Close(){
        mysql_close( self::$connection_handle );
    } 

    public static function Query( $query ){
        self::Connect();   
            $result = mysql_query( $query, self::$connection_handle );
            if( !$result ){
                die( 'Error: ' . mysql_error() );
            }else{
                $DatabaseQuery = new DatabaseQuery();
                    $DatabaseQuery->$result = $result;       
                    $DatabaseQuery->$mysql_num_rows = mysql_num_rows($result);

                return &$DatabaseQuery;
            }
        self::Close();
    } 
}
但是返回指针引用不起作用?事实上,我并不是最新的PHP指针,有人能解释一下我做错了什么吗

这是因为我正在函数中声明DatabaseQuery类的新实例,不是吗。 HELPPP:)

编辑::///////

我已经完成了我的课程,看起来是这样的:

class DatabaseQuery{
    public $result;
    public $mysql_num_rows;        
}

class Database{    
    private static $name = '';
    private static $user = '';
    private static $password = '';   
    private static $host = 'localhost';
    private static $prefix = '';   
    private static $connection_handle = null;

    protected function Connect(){
        self::$connection_handle = mysql_connect(self::$host, self::$user, self::$password); 

        if( !self::$connection_handle ){
            die( 'Could not connect: ' . mysql_error() );
        }else{
            mysql_select_db( self::$name, self::$connection_handle );
        }
    }

    protected function Close(){
        mysql_close( self::$connection_handle );
    } 

    public static function FetchQueries( &$queries ){
        $db_query = array();
            self::Connect();   
                foreach( $queries as $key => $query ){
                    $result = mysql_query( $query, self::$connection_handle );
                    if( !$result ){
                        die( 'Error: ' . mysql_error() );
                    }else{
                        $DatabaseQuery = new DatabaseQuery();
                            $DatabaseQuery->result = $result;       
                            $DatabaseQuery->mysql_num_rows = mysql_num_rows($result);  
                            $db_query[ $key ] = $DatabaseQuery; 
                    }
                }
            self::Close();
        return $db_query;
    } 
}
现在您可以用模型视图控件(MVC)的方式调用它,因为您正在顶部(或在单独的文件中)定义所有数据


您能告诉我您对这种MVC方法的看法吗?

您应该使您的
数据库
类成为可实例化的。现在,您正在为每个查询打开一个新的连接,这会带来糟糕的性能(非常糟糕)。您可以将这个类设置为单例(事实上通常就是这样做的,因为通常只有一个到DB的连接是有意义的)

因此,您的代码(非常简化)应该如下所示:

class Database
{
  private static $instance;

  protected function __construct() {
    self::$instance = mysql_connect(...);
    // do some error checking!
  }

  protected function __clone() {}

  public static function getInstance() {
    if (!isset(self::$instance)) {
      self::$instance = new Database();
    }
    return self::$instance;
  }

  public function query($sql) {
    do mysql_query(...) and error checking, return $result or your own DatabaseQuery()
  }
}
通过这种方式,您不能直接进行调用静态函数的查询,但可以在此类中添加另一个函数:

public static function makeQuery($sql) {
  $db = self::getInstance();
  return $db->query($sql);
}
要将此类用于实例,应调用
$db=Database::getInstance(),而$db是一个数据库对象,您可以正常调用它的公共方法。如果您只想继续进行静态调用以进行查询,只需调用
$result=Database::makeQuery($sql)
。无论哪种方式,都可以保证您只有一个到数据库的连接(这是singleton所做的),这样您就不会有当前为每个查询启动新连接的开销


<强>也<>强>考虑使用或替代旧的和<强>不推荐的< /强> <代码> MySqL**<代码>函数(参见上面的警告)。有关每个API的更多信息和好处,请参见

是否与私有静态相同?我打算在页面开始时创建$query一个查询数组,以便尝试和维护MVC类型的布局。我在我的帖子中添加了一个新的编辑,我非常感谢您查看并了解您的想法?你能看到我可能遇到的任何问题吗?@JamesT protected是
public
private
的混合体。您可以从子类访问受保护的属性/方法,但不能从外部访问。它与
静态
无关,但是如果您愿意,可以使用
受保护的静态
属性/方法。@JamesT您的新编辑应该可以工作,但我真的认为它不是一个好的设计。如果您扩展了框架,您可能会看到需要在应用程序的其他部分执行查询(考虑使用观察者模式或插件系统:您将希望在插件处理程序中执行查询)以获得更为灵活的代码和示例,请参见:-也考虑直接使用PDO或MyQuLi,他们已经提供了预先制作的对象,你可以节省整个代码。
public static function makeQuery($sql) {
  $db = self::getInstance();
  return $db->query($sql);
}