2017-12-10 3 views
0

データベースとのやりとりに使用できる独自のクラスを作成したいと思っています。メソッド連鎖を使用すると簡単で読みやすくなります。 しかし、最初のメソッドを静的に呼び出す際に問題があります。上記のように、私が最初にgetInstance()方法を使用する場合最初のメソッドでは "::"、残りのメソッドチェーンでは " - >"でメソッドを呼び出す方法

<?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>'; 

実際には、このコードが正常に動作し:ここ

コードです。しかし、私は私のような静的メソッドとしてselect()メソッドを直接呼び出すとき、それがどのように機能するかを行うことができます。

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

私は私のようなエラーになります上記のコードを実行した場合:

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

私はselect()メソッドが::で呼び出す前に静的メソッドでなければならないことを知っていますが、どうすれば静的にすることができますか?

+0

静的メソッドでは '::'のみ、インスタンスメソッドでは ' - > 'を使用できます。 'Crud :: getInstance() - > select( 'nama'、 'teks') - > from( 'chat')のように、静的メソッドでインスタンスを取得し、 - > get(); ' –

+0

コメントありがとうございます。現在私はまだselect()メソッドで静的を適用する方法について疑問を持ち、他のメソッドには ' - >' assignを続けることができます。私はまだこれを解決する方法を知らない:( – Mhari

+0

私のより詳細な答えを見てください。短いバージョンでは、魔法のメソッドを使って、インスタンスメソッドが静的メソッドであると見せかけることが可能になることがありますが、それは簡単ではありません。 –

答えて

-1

静的メソッドでは::、インスタンスメソッドでは->のみ使用できます。

オプション1:これは、2つのオプションであなたを残し

Crud::getInstance()->select('nama', 'teks')->from('chat')->get(); 
:あなたはこのように、チェーンに->を使用し、あなたの静的メソッドでインスタンスを取得する必要があり

の連鎖する前に明示的にインスタンスを取得します。

オプション2:マジックメソッドでファンシーを手に入れよう

他の選択肢は、magic methodsでおなじみです。メソッドprotectedまたはprivateを作成した場合は、__call()__callStatic()という魔法のメソッドを使用して、クラス外のメソッドへの呼び出しを傍受することができます。 __callStatic()の場合は、self::getInstance()を呼び出してインスタンスを使用するように切り替えることができます。

このアプローチは、あなたが

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

ような何かをやらせるだろう。ここアイデア(demo on 3v4l)を実証するためのいくつかの非常に簡略化されたサンプルコードは次のとおりです。

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 

このすべての重要な注意点:何Eloquent, the ORM that ships with Laravelを改めて再考するような見た目をしています。前に自分自身のORMを作った人からそれを取ってください。すでに書かれ、徹底的にテストされているEloquentのような既存のシステムを使う方が良いです(Laravelフレームワーク全体を使わなくても使用できます)。 ORMを構築するのはです。それは見た目よりもずっと硬く、一度始めるとウサギの穴が深くなっていきます。

+0

ありがとうございました。私はちょうど私がそれを開発して学ぶことができる自分自身を作成し​​ようと思っています:)。何かのために時間通りに返信しないと申し訳ありません。 – Mhari

関連する問題