2017-12-10 2 views
0

aufrufen Ich möchte meine eigene Klasse, die ich für die Interaktion mit einer Datenbank verwenden kann, und ich denke, es wäre einfach und lesbar, wenn ich Methodenverkettung verwende. Aber ich habe ein Problem, die erste Methode statisch aufzurufen. Hierwie Methode mit "::" in der ersten und "->" für den Rest in Methodenverkettung

ist der Code:

<?php 

class Crud 
{ 

    protected static $action; 
    protected static $instance = null; 
    protected static $columns = []; 
    protected $data; 
    protected $db; 
    protected $query; 
    protected $table; 

    public function __construct() 
    { 
     $this->db = new mysqli('localhost', 'root', '', 'bahan_belajar'); 
     if (!$this->db) { 

      echo "error"; 
     } 
     return $this; 
    } 

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

    public function select() 
    { 
     if (empty(func_get_args())) { 
      // $this->columns = "*"; 
      self::$columns = "*"; 
     } else { 
      if (is_array(func_get_args())) { 
       // self::columns = join(', ', func_get_args()); 
       self::$columns = join(', ', func_get_args()); 
      } else { 
       // self::columns = func_get_args(); 
       self::$columns = func_get_args(); 
      } 
     } 

     self::$action = "SELECT"; 
     return $this; 
    } 

    public function from($tableName) 
    { 
     $this->table = ' FROM ' . $tableName; 
     return $this; 
    } 

    public function get($getName = 'object') 
    { 
     $this->query = self::$action . ' ' . self::$columns . ' ' . $this->table; 
     switch ($getName) { 
      case 'object': 
       $this->data = $this->db->query($this->query)->fetch_object(); 
       break; 
      case 'array': 
       $this->data = $this->db->query($this->query)->fetch_array(); 
       break; 
      case 'count': 
       $this->data = $this->db->query($this->query)->num_rows; 
       break; 
     } 
     return $this->data; 
    } 
} 

$chat = Crud::getInstance()->select('nama', 'teks')->from('chat')->get(); 


echo '<pre>'; 
print_r($chat); 
echo '</pre>'; 

Eigentlich ist dieser Code funktioniert gut, wenn ich getInstance() Methode zunächst verwenden, wie oben gezeigt. Aber wie kann ich es funktioniert, wenn ich direkt an die select() Methode als statische Methode nennen wie:

$chat = Crud::select('nama', 'teks')->from('chat')->get(); 

Wenn ich führen Sie den Code oben ich einen Fehler, wie zum Beispiel:

Fatal error: Uncaught Error: Using $this when not in object context in C:\xampp\htdocs\bahan_belajar\chat\classes.php:47 Stack trace: #0 C:\xampp\htdocs\bahan_belajar\chat\classes.php(74): Crud::select('nama', 'teks') #1 {main} thrown in C:\xampp\htdocs\bahan_belajar\chat\classes.php on line 47

Ich weiß, dass die Methode select() eine statische Methode sein sollte, bevor sie mit :: (glaube ich) aufgerufen werden kann, aber wie kann ich sie statisch machen lassen?

+0

Sie können nur 'verwenden ::' mit statischen Methoden und '->' mit Instanzmethoden. Du musst eine Instanz mit deiner statischen Methode erhalten, dann benutze '->', um folgendes zu verketten: 'Crud :: getInstance() -> select ('nama', 'teks') -> von ('chat') -> get(); ' –

+0

ja danke fürs Kommentieren. momentan frage ich mich noch, wie ich statisch auf die select() methode anwenden kann und mit '->' für andere methoden zugewiesen werden kann. Ich weiß immer noch nicht, wie man das löst :( – Mhari

+0

Siehe meine ausführlichere Antwort.Die kurze Version ist, dass es möglich ist, magische Methoden zu verwenden, damit Sie vorgeben, dass Instanzmethoden statische Methoden sind, wenn es nötig ist, aber es ist nicht einfach. –

Antwort

-1

Sie können nur :: mit statischen Methoden und -> mit Instanzmethoden. Dies lässt Sie mit 2 Möglichkeiten:

Option 1: Holen Sie sich einen Instanz Explizit Vor Chaining

Sie müssen eine Instanz mit statischen Methode zu bekommen, dann -> zu Kette verwenden, wie folgt aus:

Crud::getInstance()->select('nama', 'teks')->from('chat')->get(); 

Option 2: Erhalten Sie mit magischen Methoden Phantasie

Ihre andere Wahl ist, mit magic methods Fantasie zu bekommen. Wenn Sie Ihre Methoden protected oder private machen, können Sie Anrufe auf diese Methoden abfangen von außerhalb der Klasse mit den __call() und __callStatic() magischen Methoden. Wenn Sie sich in __callStatic() befinden, können Sie zur Verwendung einer Instanz wechseln, indem Sie self::getInstance() aufrufen.

würden Sie tun so etwas wie

Crud::select('nama', 'teks')->from('chat')->get(); 

Hier einige sehr vereinfachte Beispielcode die Idee (demo on 3v4l) Dieser Ansatz lassen zu demonstrieren:

class Test 
{ 
    public static $instance; 
    protected $myVar = 'foo'; 

    // This intercepts instance calls ($testObj->whatever()) and handles them 
    public function __call($name, $args) 
    { 
     return call_user_func_array(array($this, $name), $args); 
    } 

    // This intercepts instance calls ($testObj->whatever()) and handles them 
    // The use of self::getInstance() lets us force static methods to act like instance methods 
    public static function __callStatic($name, $args) 
    { 
     return call_user_func_array(array(self::getInstance(), $name), $args); 
    } 

    public static function getInstance() 
    { 
     return self::$instance ? : new self; 
    } 

    protected function getMyVar() 
    { 
     echo $this->myVar; 
    } 

    protected function setMyVar($value) 
    { 
     $this->myVar = $value; 
     return $this; 
    } 
} 

echo Test::setMyVar(15)->getMyVar(); // successfully echoes 15 

Ein wichtiger Hinweis auf all dies: was Sie tun sieht aus wie neu erfinden Eloquent, the ORM that ships with Laravel. Nehmen Sie es von jemandem, der sein eigenes ORM schon einmal gebaut hat: Sie sollten besser ein existierendes System wie Eloquent verwenden, das bereits geschrieben und gründlich getestet wurde (und verwendet werden kann, ohne dass Sie das gesamte Laravel-Framework verwenden müssen). Ein ORM zu bauen ist viel härter als es aussieht, und sobald Sie beginnen, wird das Kaninchen Loch immer tiefer.

+0

danke .. es funktioniert wie erwartet. ich will nur versuchen, mein eigenes zu schaffen, dass ich mich entwickeln und davon lernen kann :). Tut mir leid, nicht rechtzeitig zu antworten, weil etwas .. – Mhari

Verwandte Themen