2013-12-20 2 views
0

Проблема: Когда я загружаю модель с объектом load, она НЕ вернет вторую модель.OOP PHP load не возвращает правильный объект

Посмотрите на класс Test, где я загружаю модель с объектом load. Код $this->two вернет объект One (должен загрузить объект Two).

Вопрос: Как решить эту проблему? Я открыть ваши предложения/идеи/код

Текущий результат:

one is working 
object(One)#3 (1) { ["error":"Model":private]=> NULL } 
one is working 
object(One)#4 (1) { ["error":"Model":private]=> NULL } 

Правильный результат:

one is working 
object(One)#3 (1) { ["error":"Model":private]=> NULL } 
two is working 
object(Two)#4 (1) { ["error":"Model":private]=> NULL } 

PHP:

one_model.php

<?php 

class One extends Model { 

    public function test() { 
     echo '<p>one is working</p>'; 
    } 

} 

two_model.php

<?php 

class Two extends Model { 

    public function test() { 
     echo '<p>two is working</p>'; 
    } 

} 

index.php

<?php 

class Controller { 

    public $load; 

    public function __construct() { 
     $this->load = new Load(); 
    } 

} 

class Load { 

    public function model($name) { 
     if (!class_exists($name)) { 
      require(strtolower($name) . '_model.php'); 
     } 
     $model = new $name; 
     return $model; 
    } 

} 

class Model extends PDO { 

    private $error; 

    public function __construct() { 

     $options = array(
      PDO::ATTR_PERSISTENT => true, 
      PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 
     ); 

     try { 
      $dsn = "mysql:dbname=test;host=localhost;charset=utf8"; 
      parent::__construct($dsn, 'root', '', $options); 
     } 
     catch (PDOException $e) { 
      $this->error = $e->getMessage(); 
     } 
    } 

} 

class Test extends Controller { 

    public $one; 
    public $two; 

    public function __construct() { 
     parent::__construct(); 

     $this->one = $this->load->model('one'); 
     $this->two = $this->load->model('two'); 
    } 

    public function testing() { 
     $this->one->test(); 
     var_dump($this->one); 
     $this->two->test(); 
     var_dump($this->two); 
    } 

} 

// Usage 
$test = new Test(); 
$test->testing(); 
+0

Вы уверены, что вторая модель сохраняется правильно? Тестирование кода на моем тестовом сервере, это дает мне правильный результат. – Atli

+0

Игнорируйте это. Я удалил код PDO, потому что это не показалось актуальным для теста, но добавление его, похоже, вызывает проблему. По крайней мере, это хорошая подсказка, где проблема: – Atli

+0

Да, я заметил, что расширение PDO вызывает эту проблему. Но мне нужно, чтобы он расширялся для модели. –

ответ

0

Я переместил оболочку PDO из модели для разделения класса и создал объект для подключения к базе данных.

Это хороший подход? Есть еще значений "waste of resources"?

class Database extends PDO { 

    private $error; 

    public function __construct() { 

     $options = array(
      PDO::ATTR_PERSISTENT => true, 
      PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 
     ); 

     try { 
      $dsn = "mysql:dbname=test;host=localhost;charset=utf8"; 
      parent::__construct($dsn, 'root', '', $options); 
     } 
     catch (PDOException $e) { 
      $this->error = $e->getMessage(); 
     } 
    } 

} 


class Model { 

    public $db; 

    public function __construct() { 
     $this->db = new Database(); 
    } 

} 
+0

Если для параметра ATTR_PERSISTENT установлено значение true, это будет не так уж плохо по причинам, описанным в моем ответе, но для непостоянного кода вы хотите избежать инициализации более чем одного экземпляра PDO. – Atli

+0

В общем, постоянные подключения довольно безопасны. Сделайте им снимок в своем веб-приложении и посмотрите, как он преформирует. Источник: [http://bitfluxx.com/2008/04/11/why-you-should-use-persistent-connections-with-mysql.html](http://bitfluxx.com/2008/04/11/ why-you-should-use-persistent-connections-with-mysql.html) –

+0

Где я должен использовать '__dectructor' для закрытия соединения? В классе 'controller' /' database'/'model'? –

-1

Проблема есть, кажется, что вы передаете PDO::ATTR_PERSISTENT => true конструктору PDO. Это укажет PDO на кэширование и повторное использование соединений - как вы, несомненно, намереваетесь, но также, по-видимому, вызывает PDO для создания клонов первого экземпляра PDO, сгенерированного в рамках одного сценария, включая дочерний класс, используемый для создания этого первого экземпляра , (По-видимому, это не так много документации.)

Если вам нужны постоянные соединения, моя рекомендация заключалась бы в том, чтобы определить модели таким образом, чтобы они не расширялись от PDO. В любом случае это действительно не обязательно.

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

class DatabaseSingleton { 
    private static $instance; 

    public static function get() { 
     if (!self::$instance) { 
      $options = array(
       PDO::ATTR_PERSISTENT => true, 
       PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 
      ); 
      $dsn = "mysql:dbname=test;host=localhost;charset=utf8"; 
      self::$instance = new PDO($dsn, 'root', '', $options); 
     } 
     return self::$instance; 
    } 
} 

abstract class Crud { 
    private $pdo; 

    public function __construct() { 
     $this->pdo = DatabaseSingleton::get(); 
    } 

    public function create(...) { 
     $this->pdo->... 
    } 
    public function retrieve(...) { 
     $this->pdo->... 
    } 
    public function update(...) { 
     $this->pdo->... 
    } 
    public function delete(...) { 
     $this->pdo->... 
    } 
} 

Тогда ваши модели могут быть определены просто как дети:

abstract class Model extends Crud { 

    public function __construct() { 
     parent::__construct(); 
     // Etc... 
    } 
} 

и функциональность CRUD, определенной в Crud будут доступны для них, используя один экземпляр PDO, предоставляемый синглтоном.

+0

-1: потому что - singleton. –

+0

@ tereško И что именно не так с использованием синглтона в этой ситуации? – Atli

+0

То же самое, что с ним связано ** в каждом другом ** случае: он создает связную связь и вводит глобальные состояния. –

Смежные вопросы