Although everyone’s programming style is different, some suggestions can make your code more standard and stable. The following points are summarized in this website update, hoping to help you learn and use Yii2.
The environment that
- Server environment: CentOS
- Development environment and IDE: MAC & PHPStorm
- Yii: v2.0.15 base version
Next up
Before the development of
First, let’s talk about things before development. We will configure YiI2 to a state that is easiest to develop.
Composer
In addition to making it easier to install Yii2 and third-party extensions, being able to use Composer means that your server can at least run PHP-CLI. Then you can use the YII command line, which will bring endless traversal to your development.
For Composer, there are some key words that you should pay special attention to: install, update, require.
cultural
When yii2 is installed by default, the relevant information of the program is in English. The first step is to change it to Chinese, which is very simple.
// config/web.php
'language'= >'zh-CN'
Copy the code
Static cache problem
When using Yii2, we used to manage static files (images, CSS files, JS files, etc.) in resource classes. However, there may be browser cache problems, which can be avoided through configuration during development, especially when developing mobile pages.
// config/web.php
'assetManager'= > ['appendTimestamp'= >true].Copy the code
Configure the DB
Although Yii2 is database friendly, especially mysql, we should still use a stable and higher version. Not to mention that your application will not have a mobile terminal in the future, choosing an emoji-supporting database early on will prevent us from downloading a third-party library to solve the error problem.
If you can
- Mysql5.3.3 +
- The config/db. PHP charset = utf8mb4
Configure the debug
If possible, configure a PHP extension similar to XDEBUG and integrate it into your IDE. You will inevitably encounter bugs that are difficult to catch during the development process. This requires you to continuously observe the values and assignment paths of certain variables during the life cycle of yiI2. For specific configuration, please refer to my previous course, using Xdebug to support yiI2 debugging – PhpStorm configuration
Of course, Yii2’s own debug extension is also extremely useful, especially when configuring urlManager.
The development of
Here are some of my habits and tips for yiI2 development that I hope will prove useful to you.
Single responsibility
A class and a method should have only one responsibility, as shown in the following code
function getFullName(a){
$isAdmin = Administrator::find()->where(['user_id'= >$this->id])->one();
if($isAdmin && $this->xxx == 1) {return $this->first_name . "" . $this->last_name; }}Copy the code
For example, in the case above, it would be best to separate out the judgment about being an administrator, as follows
function getFullName(a){
if($this->isAdmin() && $this->xxx == 1) {return $this->first_name . "" . $this->last_name; }}function isAdmin(a){
return Administrator::find()->one();
}
Copy the code
Each approach is a minimal problem solving unit, for which you can read refactoring – Improving Existing Code, a book he read about three years ago.
The importance of models
A lot of yii2 beginners like to write a lot of logic into the actions of the controller. This is not correct. Our focus should be on the model, and the controller is only the input and output.
Let’s take associations for example. The following code is bad.
// A controller
public function actionIndex(a){
// There is more code here.// Get the order set of a member from three days ago
$order = Order::find()->where(["user_id"=>$userId])->andWhere([">"."created_at",strtotime(date("Y-m-d",time()))- 86400.*3])->all();
}
Copy the code
It is best to put this logic into the membership model
/ / User model
public function recent3DaysOrders(a){
return Order::find()->where(["user_id"= >$this->id])->andWhere([">"."created_at",strtotime(date("Y-m-d",time()))- 86400.*3])->all();
}
// In the controller
public function actionIndex(a){
$order = $user->recent3DaysOrders();
}
Copy the code
The controller code strives to be simple, doing only basic input selection and output rendering.
The rules
Right and wrong, don’t write casually.
// Action of a controller
public function actionCreate(a){
$model = new User();
if(Yii::$app->request->isPost){
$model->load(Yii::$app->request->post());
if($model->xxx == xxxx){
// todo
}
if($model->save()){
//}}}Copy the code
The code above is very familiar, and this is what we expect, but sometimes the input is not as honest as it should be, and we need to do more validation. Please do not write validation directly into the action, such as the if judgment in the code above.
** Leave validation to the rules and scenarios of the model. * * all.
Always think of reuse (small widgets)
The principle of coding is to reuse as much code as possible, especially widgets, which allow reuse in the view layer, widgets are very easy to use
Create a “Components” folder under @app
Create a Widget class in components (must inherit from yII \ Base \Widget)
3. Render a small widget view (under Components/Views if needed)
4. Use it
Don’t get it? Let me give you an example.
// components/Top10.php
namespace app\components;
use yii\base\Widget;
class Top10 extends Widget {
public function init(a){
parent::init();
}
public function run(a){
parent::run();
return $this->render('top10'); }}Copy the code
Write a view
// components/views/top10.php
<h1>Hello Top10</h1>
Copy the code
Use it
// A view
<?= \app\components\Top10::widget();? >
Copy the code
Widgets can be complex, such as ActiveForm, GridView, and so on. I also wrote an article about small pendants before, if you are interested, you can read it. portal
Be careful with AR associated loops
The problem, as I mentioned in the previous video, is lazy loading versus instant loading. For example, the following code is not good
$customers = Customer::find()->limit(100)->all();
foreach ($customers as $customer) {
// SELECT * FROM `order` WHERE `customer_id` = ...
$orders = $customer->orders;
}
Copy the code
The above code executed 101 queries. What if there was more data? Here’s how we solved the above problem.
// SELECT * FROM `customer` LIMIT 100;
// SELECT * FROM `orders` WHERE `customer_id` IN (...)
$customers = Customer::find()
->with('orders')
->limit(100)
->all();
foreach ($customers as $customer) {
// There is no SQL execution
$orders = $customer->orders;
}
Copy the code
Reduced from 101 queries to 2.
Make your code “clean”
By simplicity, I don’t mean the amount of code, but the meaning. Take the following code for example
1 / / way
if($num > 100) {return 1
}else{
return 2
}
2 / / way
return $num > 100 ? 1 : 2;
Copy the code
We all like the second option when the logic is simple, but if the logic is more complex, I prefer option 1. Although it may be many lines, the idea is concise, so that you can understand it and he can understand it.
Why bother writing an expression that makes you feel awesome!!
Add a try to the view’s PHP code
When writing actions or model methods, we usually use try…. to ensure code stability Catch syntax, but rarely used in the view of yii2, remember, use it too! Take this code for example.
/ / view
<?= \app\components\WechatLangSideMenu::widget();? >
Copy the code
What if the above code fails? I recommend writing it as follows
try {
echo \app\components\WechatLangSideMenu::widget();
}catch(\Exception $e){
// You can write your own error handling without handling.
}
? >
Copy the code
Caution is the parent of safety.
Do not write dead, use constant or configuration.
Some code requires some judgment, and the reference to judgment is certain values, such as the code below
if($this->type === 1) {return "Article";
}else if($this->type === 2) {return "Column";
}
Copy the code
I recommend it
if($this->type === Item::ARTICLE_TYPE){
return "Article";
}else if($this->type === Item::TOPIC_TYPE){
return "Column";
}
Copy the code
ARTICLE_TYPE and TOPIC_TYPE are constants of the Item model.
Using migration scripts
As I’ve said many times before, and again this time, use migration to manage the database portion of a YIi2 program.
And these scripts should be put together in your version control. Remember, migration scripts usually have two parts.
- Structure of the script
- Import of seed data
Many people ignore the second category. In addition, if your table has a prefix when doing the migration script, it will be written as follows in the script
{{%user}}// discuz_user
Copy the code
A matter of time
When using yii2 to develop mysql web applications, we like to use time stamps for the time class fields of the data table. Generally, there will be fields of record generation time and update time in the table.
Please use the built-in TimestampBehavior class of Yii2 for their updates, then we don’t need to worry about filling the field data, as shown in the following code
namespace app\models;
use Yii;
use yii\behaviors\TimestampBehavior;
class Article extends \yii\db\ActiveRecord {
public function behaviors(a){
return[['class'=> TimestampBehavior::className(), ] ]; }}Copy the code
Therefore, I recommend naming the time field in the data table as follows
- Generation time created_at
- Update time updated_AT
The above code is sufficient without specifying fields.
Remember: Remove the required restriction in rules for created_AT and updated_AT fields.
Parent class or behavior
In fact, I do not exclude any kind of, each has its own advantages and disadvantages, the parent class is simple to use but increased coupling, behavior coupling degree is low but configuration is more complex than the direct parent class.
Conceptually, of course, it’s a little different
- Behavior attributes attached to some classes
- Parent class Attributes common to classes
My usage (not necessarily right), especially in modules I like to add a parent class to the controller.
To develop the
After the program is developed, there are still some configurations for yii2 program, many of which you must already know.
Entrance to the file
First, we need to change the operation mode of YIi2 from development mode to production mode. The general code is as follows
// index.php
defined('YII_DEBUG') or define('YII_DEBUG'.false);
defined('YII_ENV') or define('YII_ENV'.'prod');
Copy the code
An error page
For a stable program, it doesn’t matter if you report an error, what matters is how you handle it after reporting an error. Since users think it is good and helpful to developers, I wrote an article before, you can see “Implementing YouTube Style error handling page with Yii2”.
urlManager
Strictly speaking, this should be done in the development phase. In order to make the search engine better, and to increase the security of the application, we should beautify the URL, such as
/index.php? r=admin/user/index/ / into/admin/user - index. HTML
Copy the code
For details about urlManager configuration and common Web server configuration, you can see the quick check table I wrote before, there are ready-made codes.
summary
Accidentally write so much, of course yiI2 development should pay attention to more than these, later slowly say.