PHP code is getting too complex in pursuit of unlimited flexibility.
Many believe that this is the only right way.
All problems in computer science can be solved by another level of indirection… except for the problem of too many layers of indirection
David Wheeler
*Except PECL and microframeworks
php composer.phar create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic
cd basic
php -S localhost:80
or
bootstrap
validation and forms
debugger
remembers everything
can search logs
useful errros
useful fatals
try {
file_get_contents('test');
} catch (\yii\base\ErrorException $e) {
// okay :(
}
code generator
generating controller
preview
diff
console
Extensions are easy to install:
php composer.phar require --prefer-dist yiisoft/yii2-mongodb "*"
that's it. You can use it now.
More than 250 unofficial extensions
Consistent syntax for everything.
$query = new \yii\db\Query;
$query->select('id, name')
->from('tbl_user')
->orderBy('id DESC')
->limit(10);
$command = $query->createCommand();
echo $command->sql;
$rows = $command->queryAll();
$users = User::model()->find()
->orderBy('id DESC')
->limit(10)
->all();
$finder = Post::find()->where(['a' => 10]);
$finder2 = clone $finder;
$finder2->addWhere(['b' => 1]);
$model = $finder->one();
$model2 = $finder2->one();
// shortcuts
$post = Post::findOne(10); // pk = 10
$post = Post::findOne(['a' => 10, 'b' => 1]); // where a = 10 and b = 1
has one, has many. Declared as methods.
class User extends \yii\db\ActiveRecord
{
public function getPosts()
{
return $this->hasMany('Post', ['user_id' => 'id']);
}
public function getActivePosts()
{
return $this->hasMany('Post', ['user_id' => 'id'])
->where(['status' => Post::STATUS_ACTIVE]);
}
}
$posts = $user->getPosts()->limit(10)->all();
$postCount = $user->getPosts()->count();
class Post extends \yii\db\ActiveRecord
{
public function getTags()
{
return $this->hasMany(Tag::className(), ['id' => 'tag_id'])
->viaTable('post_tag', ['post_id' => 'id']);
}
}
$posts = Post::find()->limit(10)->asArray()->all();
foreach($posts as $post) {
echo $post['title']."\n";
}
When calling save()
only changed attributes are saved.
There are link
and unlink
to manage relations.
$comment = new Comment();
$comment->text = 'Hello, Yii!';
// INSERT INTO post_comment ...
$post->link('comments', $comment);
// DELETE FROM post_comment ...
$post->unlink('comments', $comment);
// 10 records at a time
foreach (Customer::find()->batch(10) as $customers) {
// $customers — array of 10 or less records
}
// 10 records at a time, iterating one by one
foreach (Customer::find()->each(10) as $customer) {
// $customer — Customer object
}
// eager loading
foreach (Customer::find()->with('orders')->each() as $customer) {
}
setMyCoolFactoryDependencyInjectionContainer()
in Yii
Well-thought API, 80% of use cases, sensible defaults, ability to extend.
namespace app\controllers;
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = 'app\models\User';
public function actionSearch($keyword) // !!!
{
$result = SearchService::search($keyword);
return $result;
}
}
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'user'
],
],
]
curl -i -H "Accept:application/json" "http://localhost/users"
HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By: PHP/5.4.20
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
[
{
"id": 1,
...
},
{
"id": 2,
...
},
...
]
1.1 is stable and supported till at least 2016