2010-12-16 2 views
12

Я пытаюсь написать функцию PHP. Это очень просто. Это просто подготовленный оператор, который запрашивает базу данных, но я не могу заставить это работать. Я продолжаю получать сообщение об ошибке для вызова функции-члена() для не-объекта. вот код:Вызов функции-члена prepare() для не-объекта Справка PHP

$DBH = new mysqli("host", "test", "123456", "dbname"); 
function selectInfo($limit, $offset){ 
    $stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?"); 
    $stmt->bind_param("ii", $limit, $offset); 
    $stmt->execute(); 
    } 
selectInfo(); 

Каждый раз, когда я вызываю функцию, я получаю эту ошибку. Кто-то может помочь?

ответ

43

Это ошибка обзорное. Вы делаете $DBH глобальной переменной. Поэтому, когда вы вводите функцию, глобальная переменная недоступна. У вас есть 5 реальных вариантов.

1. Используйте глобальное ключевое слово

function doSomething() { 
    global $DBH; 
    //... 

Это не очень хорошая идея, так как это делает обслуживание и тестирование пита. Представьте, что вы пытаетесь отладить этот вызов функции. Теперь вы должны пойти узнать, где $DBH определяется, чтобы попытаться выяснить, что происходит ...

2. Сделайте $DBH параметр для функции

function doSomething(MySQLi $DBH) { 

Это имеет преимущество в том, явный. Но это все еще не здорово, так как код вызова должен отслеживать глобальную переменную.

3. Создайте функцию «получить» $DBH объекта

function getDBH() { 
    static $DBH = null; 
    if (is_null($DBH)) { 
     $DBH = new mysqli(...); 
    } 
    return $DBH; 
} 

function doSomething() { 
    $DBH = getDBH(); 
} 

Это имеет преимущество, обходящие глобальную переменную проблема полностью. Но также сложно иметь несколько подключений или повторно использовать какой-либо код для других подключений.

4. Создайте класс обернуть доступ к базе данных

class Database { 
    public function __construct($host, $user, $pass) { 
     $this->DBH = new MySQli($host, $user, $pass); 
    } 
    public function doSOmething() { 
     $this->DBH->foo(); 
    } 
} 

Это инкапсулирует все для вас. Весь доступ к базе данных будет проходить через один класс, поэтому вам не нужно беспокоиться о доступе к глобальной переменной или о чем-либо еще.

5. Используйте предварительно построенный класс/рамки

Это самый лучший вариант, так как вам не нужно беспокоиться о том делать это самостоятельно.

Классы доступа к базе данных:

  • A quick google search to get you started
  • Doctrine ORM - Полная библиотека доступа к базам данных с полным ORM (Mapping Object)
  • ADODB - библиотека базы данных агностик доступа к базе данных
  • Pear MDB2 - Другая база данных библиотека доступа

Полное рамочные:

  • Zend Framework
  • Lithium Framework
  • Code Igniter
  • (на самом деле там гораздо больше, я не буду беспокоить листинг больше, так как это еще один вопрос, все вместе ...)

Действительно, выбор бесконечен. Найдите то, что вам нравится, и придерживайтесь его. Это действительно облегчит вашу жизнь ...

Удачи!

3

Попробуйте добавить global $DBH; в функцию или добавить его в параметры функции.

3
selectInfo($DBH); 

function selectInfo($DBH,$limit, $offset){ 
    $stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?"); 
    $stmt->bind_param("ii", $limit, $offset); 
    $stmt->execute(); 
    } 
7

$DBH нет в наличии. Вы либо хотите определить $DBH как глобальные в функции:

$DBH = new mysqli("host", "test", "123456", "dbname"); 
function selectInfo($limit, $offset){ 
    global $DBH; 
    $stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?"); 
    $stmt->bind_param("ii", $limit, $offset); 
    $stmt->execute(); 
} 

или ircmaxell отметил в своем замечательном ответе есть функция, которая возвращает статический экземпляр $DBH.

+0

Спасибо. Как я могу сделать это глобальным и все еще держать вещи в безопасности? Я бы обернул соединение в функцию и назначил ему переменную вроде функции connect() {new myqsli («host», «test», «123456», «dbname»)} $ DBH = new connect(); (Переменные соединения фактически скрыты в другом файле.) – mcbeav 2010-12-16 17:19:49

+0

Да, я бы сделал какую-то функцию и захватил соединение оттуда. – Jim 2010-12-16 17:22:38

3

Это просто. $DBH не существует в пределах selectInfo() функция. Переменная, определенная в глобальной области видимости, не будет видна внутри функции и наоборот. Подробнее о variables scope на страницах руководства.

Как это решить? Передайте эту переменную в качестве аргумента функции:

$dbh = new MySQLi(...); 

function selectInfo(MySQLi $dbh, $limit, $offset) { 
    $stmt = $dbh->prepare(...); 
    ... 
} 
3

Убедитесь, что соединение выполнено успешно.

$DBH = @new mysqli("host", "test", "123456", "dbname"); 

if ($DBH->connect_errno) { 
    die('Connect Error: ' . $DBH->connect_errno); 
} 

или

$DBH = @mysqli_connect("host", "test", "123456", "dbname"); 

if (!$DBH) { 
    die('Connect Error: ' . mysqli_connect_errno()); 
} 
0

Создание $ ДВГ глобальный не здоров ... за исключением того, что вы можете сделать свой $ ДВГ защищены в классе и установить его в нуле .. и использовать его ..

0
class PDOconnect extends PDO{ 

защищены $ CON = ноль;

public function __construct(){ 
       try {  

        $this->con= new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD); //our new PDO Object 

         $this->con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);      
         $this->con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);      
         $this->con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
         echo "hi.. you are connected succcessfully..."; 
        } 
Смежные вопросы