首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP「Using $this when not in object context」錯誤原因與修復

     編輯:PHP 相關知識

錯誤現象

Fatal error: Using $this when not in object context in ... on line XX

核心原因

在 `static` 靜態方法中使用了 `$this`。靜態方法屬於類,不屬於任何實例,因此沒有 `$this` 指針。

錯誤代碼示例

class DB {
    private $link_id;

    public static function _init(array $dsn) {
        // 錯誤:靜態方法中調用 $this->link_id
        if (!$this->link_id = @mysql_connect($dsn['host'], $dsn['user'], $dsn['pwd'])) {
            // ...
        }
    }
}

修復方案

方案一:改為實例方法(推薦,符合 OOP 封裝)

class DB {
    private $link_id;

    public function __construct(array $dsn) {
        $this->connect($dsn);
    }

    private function connect(array $dsn): void {
        $this->link_id = @mysql_connect($dsn['host'], $dsn['user'], $dsn['pwd'])
            ?: throw new RuntimeException('DB connect failed');
    }

    // 靜態工廠方法返回實例
    public static function create(array $dsn): self {
        return new self($dsn);
    }
}

// 使用
$db = DB::create($dsn);

方案二:若必須保持靜態,改用靜態屬性 `self::$link_id`

class DB {
    private static $link_id = null;

    public static function init(array $dsn): void {
        self::$link_id = @mysql_connect($dsn['host'], $dsn['user'], $dsn['pwd'])
            ?: throw new RuntimeException('DB connect failed');
    }

    public static function query(string $sql) {
        return mysql_query($sql, self::$link_id);
    }
}

缺點:全局單一連接,難以支持多數據庫、難以單元測試、非線程安全(PHP-FPM 多進程下各進程獨立,尚可接受)。

方案三:單例模式(折中)

class DB {
    private static ?self $instance = null;
    private $link_id;

    private function __construct(array $dsn) { /* connect */ }

    public static function getInstance(array $dsn): self {
        if (self::$instance === null) {
            self::$instance = new self($dsn);
        }
        return self::$instance;
    }
}

避坑指南

  • 靜態方法只能訪問靜態屬性/方法(`self::$prop`、`self::method()`)。
  • 實例方法可訪問 `$this->prop`、`$this->method()`、`self::$staticProp`。
  • 構造函數 `__construct` 是實例方法,可安全使用 `$this`。
  • PHP 8.0+ 引入 `static::class` 晚期靜態綁定,便於繼承場景。

補充:`mysql_*` 函數已棄用

示例中使用的 `mysql_connect` 等函數自 PHP 5.5 棄用,PHP 7.0 移除。請改用 PDO 或 mysqli**:

// PDO 單例示例
class DB {
    private static ?PDO $pdo = null;

    public static function getPDO(array $dsn): PDO {
        if (self::$pdo === null) {
            $dsnStr = "mysql:host={$dsn['host']};dbname={$dsn['db']};charset={$dsn['charset']}";
            self::$pdo = new PDO($dsnStr, $dsn['user'], $dsn['pwd'], [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES => false,
            ]);
        }
        return self::$pdo;
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved