Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the pits in the Yii2 framework?

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article will explain in detail what holes there are in the Yii2 framework. The editor thinks it is very practical, so I share it for you as a reference. I hope you can get something after reading this article.

ActiveRecord was written inexplicably?

Prepare knowledge

The basic usage of ActiveRecord. If you don't understand, please refer to here.

Code scene

/ * @ property integer $id * @ property string $name * @ property string $detail * @ property double $price * @ property integer $area * * / class OcRoom extends ActivieRecord {...} $room = OcRoom::find () / / take out an object first. -> select (['id']) / / just take out the' id' column-> where (['id'= > 20])-> one (); $room- > save (); / / Save, and you will find that the other fields in this row are written as default values.

Summarize the problem

The problem with this example is:

I fetched a row from the database, the $room in the code, but only the id field was taken out, and the other fields were naturally the default values.

When I $room- > save (), the fields that are the default values are also saved in the database. What!?

In other words, when you want to save resources, do not take out all the fields, you must be careful not to save, otherwise, a lot of data will be inexplicably changed to the default value.

Solution method

But what solution do we have? Provide several ideas:

Always pay attention to avoid the preservation of ActiveRecord that has not been completely removed.

Modify or inherit ActiveRecord so that when the object is created by find () and the field is not completely taken out, the save () method is called to throw an exception.

Modify or inherit ActiveRecord so that when this object is created by find () and the field is not completely taken out, when the save () method is called, only the checked field is saved and the other fields are ignored.

Is your Transaction working yet?

Code scene

/ * @ property integer $id * @ property string $name * * / class OcRoom extends ActiveRecord {public function rules () {return ['name','string','min'= > 2 drawing maxillary = > 10];}.} class OcHouse extends ActiveRecord {public function rules () {return [[' name','string','max'= > 10]];}.} $a = new OcRoom (); $a-> name ='' / / name is an empty string and does not meet the rules () condition. B = new OcHouse (); $b-> name ='my room'; / / name is legal and can be saved. $transaction = Yii::$app- > db- > beginTransaction (); try {$a-> save (); / / the name field is invalid and cannot be verified. False has been returned in the validate () phase, and the database storage step will not be performed, so no exception will be thrown. The $b-> save (); / / name field is legal and can be saved normally. $transaction- > commit (); / / after submitting, it was found that $a failed to save, while $b saved successfully. } catch (Exception $e) {Yii::error ($e-> getTraceAsString (), _ _ METHOD__); $transaction- > rollBack ();}

Problem summary

The problem with this code is:

You know that the purpose of $transaction is to ensure that the entire database storage code is either a complete success or a complete failure.

Obviously, in this example, transaction did not achieve the desired effect: $a because validate () did not pass, so $transation- > commit () will not report an error.

Solution method

Within the $transation block, all save () determines the return value, and if it is false, it throws an exception directly.

'YmurmMurd` is not recognized?

Code scene

OcRenterBill extends ActiveRecord {public function rules () {return [['start_time','date','format'= >' YmurmMurd'],];}} $a = new OcRenterBill (); $a = '2015-09-12 potential investors-> save (); / / will report an error and say that the format is incorrect

Problem summary

If the Yii framework reported an error in the first place, it would not be a trick. The trick is that when I was developing on Mac, this worked perfectly, but when it was published to the online environment (Ubuntu), the error of "invalid property start_time format" popped up. Referring to the official documentation, it is found that this format is the official document allowed.

Ah, ah. All kinds of trial and error, and finally found that if changed to php:Y-m-d, the world will be clean. So, if you have such a problem, thank me.

Memory leak

Code scene

Public static function actionTest () {$total = 10; var_dump ('start memory' .memory _ get_usage ()); while ($total) {$ret=User::findOne (['id'= > 910002]); var_dump (' end memory '.memory _ get_usage ()); unset ($ret); $total--;}}

The memory of the above code is growing all the time, and according to the original idea, if the variable is released, the memory will not grow all the time. Because memory is freed every time you cycle.

Analyzing the problem the above code involves the operation of the database, and we know that many parts of the database can cause memory leaks. So first shield database-related operations, I handwritten a native database query operation, found that the memory is normal, no problem.

$dsn = "mysql:dbname=test;host=localhost"; $db_user = 'root';$db_pass =' admin';// query $sql = "select * from buyer"; $res = $pdo- > query ($sql); foreach ($res as $row) {echo $row ['username'].';}

At this time, the answer is about to come out-it is the yii2 framework that is behind it.

Now that we know that the positioning problem is a problem with the yii2 framework, we can further narrow the problem.

Public static function actionTest () {$total = 10; var_dump ('start memory' .memory _ get_usage ()); while ($total) {$ret= new User (); var_dump ('end memory' .memory _ get_usage ()); unset ($ret); $total--;}}

Memory is still growing. At this point I tested one of the other yii2 classes and found that the memory was not growing. This makes you think of what the yii2 did inside the new object, which led to a memory leak. What method is implemented when it is new. The construction method of the pair _ _ construct. Then I checked step by step from model to object and found that there was no place to cause the leak.

At this time, we might as well change our way of thinking. Since it is a leak under the yii2 framework, it must be a unique function of yii2, so what function is unique to yii2 and will be executed when the new object is used?

Behavior found that behavior was really useful in my model class.

Public function behaviors () {return [TimestampBehavior::class,];}

The most common code. We know that the last place the behavior is called is yii\ base\ Component- > attachBehaviors finally located to the

Private function attachBehaviorInternal ($name, $behavior) {if (! ($behavior instanceof Behavior)) {$behavior = Yii::createObject ($behavior);} if (is_int ($name)) {$behavior- > attach ($this); $this- > _ behaviors [] = $behavior;} else {if (isset ($this- > _ behaviors [$name])) {$this- > _ behaviors [$name]-> detach ();} $behavior- > attach ($this); $this- > _ behaviors [$name] = $behavior;} return $behavior }

We looked at this code and found that he passed himself in $behavior- > attach ($this), and finally called yii\ base\ Behavior- > attach.

Public function attach ($owner) {$this- > owner = $owner; foreach ($this- > events () as $event = > $handler) {$owner- > on ($event, is_string ($handler)? [$this, $handler]: $handler);}}

Problem summary

At this time, the answer is about to come out. In order to achieve the function of behavior, Yii2 sends its own this into it so that it can register, trigger and release events. This leads to a problem of circular references. As a result, the object refcount will not be recycled for 0 all the time.

Then it will be easy. Try replacing the query with the original connection. Sure enough, memory rises very slowly, it can be said that this is a normal phenomenon. Now the memory is about 50m, and the cpu is stable at about 7%.

After the code is optimized, run the script again, about 1 minute, and the script will be finished. The point is that memory errors will not be reported again. Therefore, it is necessary to think deeply about the problem in the future. Dare to question. If you encounter this kind of memory error in the future, be sure to check your code for memory leaks. Don't think about setting the memory of php first. This will only cure the symptoms rather than the root causes.

Summary

1, in terms of development speed, with the help of gii scaffolding, you can quickly generate code, that is to say, to build a system that can add, delete, change and check, you may not have to write a single line of code, and it integrates jquery and bootstrap, and there is basically no need to write special effects and styles, which is simply a benefit for back-end programmers who are generally poor in design and aesthetic ability. However, under the trend of complete separation of the front and back ends, the coupling between the front and back ends of the Yii2 is still a bit heavy.

2. In terms of the readability of the code, Yii will not overdesign the code in order to rigidly follow a certain design pattern. Basically, classes can jump to read the source code in IDE without the help of third-party components. Yii has a slight advantage over Laravel at this point.

3. From the open source ecosystem, Yii needs strong Google ability and the ability to read English documents because of its small number of people and a little bit more partial information.

This is the end of the article on "what is the pit in the Yii2 framework". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report