Вопрос

Я хочу иметь возможность создавать классы, расширяющие класс MySQLi для выполнения всех его SQL-запросов.

$mysql = new mysqli('localhost', 'root', 'password', 'database') or die('error connecting to the database');

Я не знаю, как это сделать без глобализации объекта $mysql для использования в других моих методах или классах.

class Blog {

public function comment() {
    global $mysql;

    //rest here
}

}

Любая помощь будет оценена по достоинству.

Спасибо.

Это было полезно?

Решение

Я предлагаю создать класс Singleton DataAccess, создать экземпляр этого класса в глобальном файле конфигурации и вызвать его в своем классе блога, например $query = DataAccess::query("SELECT * FROM blog WHERE id = ".$id).

Посмотрите на шаблон Singleton, его довольно легко понять.Идеально подходит для этой ситуации.

Ваш класс DataAccess может иметь несколько методов, например query, fetchAssoc, numRows, checkUniqueValue, transactionStart, transactionCommit, transactionRollback и т. д. и т. д.Эту функцию также можно настроить как интерфейс, который реализуется классом DataAccess.Таким образом, вы можете легко расширить свой класс DataAccess для нескольких систем управления базами данных.

Вышеупомянутое в значительной степени описывает мою модель DataAccess.

Другие советы

Я работал над чем-то подобным.Я доволен этим одноэлементным классом, который инкапсулирует вход в базу данных.

<?php
class db extends mysqli
{
    protected static $instance;
    protected static $options = array();

    private function __construct() {
        $o = self::$options;

        // turn of error reporting
        mysqli_report(MYSQLI_REPORT_OFF);

        // connect to database
        @parent::__construct(isset($o['host'])   ? $o['host']   : 'localhost',
                             isset($o['user'])   ? $o['user']   : 'root',
                             isset($o['pass'])   ? $o['pass']   : '',
                             isset($o['dbname']) ? $o['dbname'] : 'world',
                             isset($o['port'])   ? $o['port']   : 3306,
                             isset($o['sock'])   ? $o['sock']   : false );

        // check if a connection established
        if( mysqli_connect_errno() ) {
            throw new exception(mysqli_connect_error(), mysqli_connect_errno()); 
        }
    }

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

    public static function setOptions( array $opt ) {
        self::$options = array_merge(self::$options, $opt);
    }

    public function query($query) {
        if( !$this->real_query($query) ) {
            throw new exception( $this->error, $this->errno );
        }

        $result = new mysqli_result($this);
        return $result;
    }

    public function prepare($query) {
        $stmt = new mysqli_stmt($this, $query);
        return $stmt;
    }    
}

Для использования вы можете иметь что-то вроде этого:

<?php
require "db.class.php";

$sql = db::getInstance();

$result = $sql->query("select * from city");

/* Fetch the results of the query */ 
while( $row = $result->fetch_assoc() ){ 
    printf("%s (%s)\n", $row['Name'], $row['Population']); 
} 
?>

Вы можете использовать ключевое слово PHP Extensions только для любого другого класса:

class MyCustomSql extends mysqli {

    public function __construct($host, $user, $password, $database) {
        parent::__construct($host, $user, $password, $database);
    }

    public function someOtherMethod() {
    }
}

$sql = new MyCustomSql('localhost', 'root', 'password', 'database') or die('Cannot connect!');

или лучше использовать агрегацию объектов вместо наследования:

class MySqlManipulator {

    private $db;

    public function __construct($host, $user, $password, $database) {
        $this->db   = new mysqli($host, $user, $password, $database);
    }

    public function someOtherMethod() {
        return $this->db->query("SELECT * FROM blah_blah");
    }
}

$mysqlmanipulator = new MySqlManipulator('localhost', 'root', 'password', 'database') or die('Cannot connect!');

Мой стандартный метод — сделать синглтон класс, который действует как метод доступа к базе данных, и базовый класс, от которого наследуется все, требующее такого доступа.

Так:

class Base {

  protected $db;

  function __construct(){
    $this->db= MyDBSingleton::get_link();
    //any other "global" vars you might want 
  }

}


class myClass extends Base {

  function __construct($var) {
     parent::__construct();// runs Base constructor
     $this->init($var);
  }

  function init($id) {
    $id=(int) $id;
    $this->db->query("SELECT * FROM mytable WHERE id=$id");
    //etc.
  }
}

Посмотри на ПДО, которые выдают исключения, которые вы можете перехватить в случае сбоя запроса.Он широко используется и протестирован, поэтому у вас не должно возникнуть проблем с поиском существующих решений при его использовании.

Чтобы внедрить его в класс вашего блога:

class Blog {

    private $_db;

    public function __construct(PDO $db) {
        $this->_db = $db
    }

    public function comment() {
        return $this->_db->query(/*something*/);
    }

}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top