オーバーロードでPHP開発をスピードアップする

問題



多くの場合、これを書く必要があります(Yiiコードの例ですが、このアプローチはどのコードにも適用できます)。

$model = new User(); $model->name = ''; if (!$model->save()) throw new RuntimeException('Can not save!');
      
      





または:

 $model = User::model()->find(); if (!$model) throw new CHttpException(404, 'User not found!');
      
      





キャッシング:

 $dependency = new \caching\TagDependency('Post'); $posts = Post::model()->cache(1000, $dependency)->findAll();
      
      





トランザクション:

 $trx = $this->getDbConnection()->beginTransaction(); try { if (!$user->makePayment()) throw new \RuntimeException('Can not complete!'); $trx->commit(); } catch (\Exception $e) { $trx->rollback(); throw $e; }
      
      







コードが多すぎる!



解決策



上記のコードは次のように短縮できます。

結果が失敗した場合に例外を発生させます。

 $model->saveException(); User::model()->findException(); Post::model()->findAllCached();
      
      







メソッドをトランザクションでラップします。

 $user->makePaymentTrx();
      
      







組み合わせも可能です。

 User::model()->findTrxCached()
      
      











これを実装する方法は?



Yiiでは、独自のActiveRecordクラスを作成し、そこからモデルを継承します。

 class ActiveRecord extends CActiveRecord { public function __call($name, $args) { if (preg_match('/^(.+)(cached|exception|trx)$/i', $name, $matches)) { switch (strtolower($matches[2])) { case 'cached': return $this->cachedMethod($matches[1], $args); case 'exception': return $this->exceptionMethod($matches[1], $args); case 'trx': return $this->trxMethod($matches[1], $args); } } return parent::__call($name, $args); } public function trxMethod($method, $args) { $trx = $this->getDbConnection()->beginTransaction(); try { $value = call_user_func_array(array($this, $method), $args); $trx->commit(); } catch (\Exception $e) { $trx->rollback(); throw $e; } return $value; } public function exceptionMethod($method, $args) { $value = call_user_func_array(array($this, $method), $args); if (!$value) throw new Exception('False result!'); return $value; } public function cachedMethod($method, $args) { $key = get_class($this) . $method . serialize($this->getPrimaryKey()) . serialize($args) . serialize($this->getDbCriteria()); $key = md5($key); $value = \Yii::app()->cache->get($key); if ($value === false) { $value = call_user_func_array(array($this, $method), $args); \Yii::app()->cache->set($key, $value, 0, new \caching\TagDependency(get_class($this))); } else { //reset scope as in find*() methods $this->resetScope(); } return $value; } }
      
      







メソッドの基礎は正規表現です:

 preg_match('/^(.+)(cached|exception|trx)$/i', $name, $matches)
      
      







ここでサフィックスを追加できます。



利点:







短所:






All Articles