Yii源码阅读笔记(三十)

Widget类是所有小部件的基类,开始,结束和渲染小部件内容的方法的注释:

  1 namespace yii\base;
  2
  3 use Yii;
  4 use ReflectionClass;
  5
  6 /**
  7  * Widget is the base class for widgets.
  8  * Widget是所有小部件的基类
  9  *
 10  * @property string $id ID of the widget.
 11  * @property \yii\web\View $view The view object that can be used to render views or view files. Note that the
 12  * type of this property differs in getter and setter. See [[getView()]] and [[setView()]] for details.
 13  * @property string $viewPath The directory containing the view files for this widget. This property is
 14  * read-only.
 15  *
 16  * @author Qiang Xue <[email protected]>
 17  * @since 2.0
 18  */
 19 class Widget extends Component implements ViewContextInterface
 20 {
 21     /**
 22      * @var integer a counter used to generate [[id]] for widgets.
 23      * @var integer 一个用于生成widget ID的计数器
 24      * @internal
 25      */
 26     public static $counter = 0;
 27     /**
 28      * @var string the prefix to the automatically generated widget IDs.
 29      * @var string widget IDs自动生成的前缀
 30      * @see getId()
 31      */
 32     public static $autoIdPrefix = ‘w‘;
 33     /**
 34      * @var Widget[] the widgets that are currently being rendered (not ended). This property
 35      * is maintained by [[begin()]] and [[end()]] methods.
 36      * @var 目前正在呈现的小部件
 37      * @internal
 38      */
 39     public static $stack = [];
 40
 41
 42     /**
 43      * Begins a widget.
 44      * 开始一个小部件
 45      * This method creates an instance of the calling class. It will apply the configuration
 46      * to the created instance. A matching [[end()]] call should be called later.
 47      * 该方法将应用配置文件创建调用类的实例,有一个[[end()]]方法相对应
 48      * @param array $config name-value pairs that will be used to initialize the object properties
 49      * @return static the newly created widget instance
 50      */
 51     public static function begin($config = [])
 52     {
 53         $config[‘class‘] = get_called_class();// get_called_class -- 后期静态绑定("Late Static Binding")类的名称
 54                                               // 就是用那个类调用的这个方法,就返回那个类,返回值中带有 namespace
 55         /* @var $widget Widget */
 56         $widget = Yii::createObject($config);//通过类名和传入的配置,实例化调用类
 57         static::$stack[] = $widget;//将实例放入正在呈现的小部件堆栈中
 58
 59         return $widget;//返回小部件实例
 60     }
 61
 62     /**
 63      * Ends a widget.
 64      * 结束一个小部件
 65      * Note that the rendering result of the widget is directly echoed out.
 66      * @return static the widget instance that is ended.
 67      * @throws InvalidCallException if [[begin()]] and [[end()]] calls are not properly nested
 68      */
 69     public static function end()
 70     {
 71         if (!empty(static::$stack)) {//正在呈现的小部件堆栈中存在调用类实例
 72             $widget = array_pop(static::$stack);//则从堆栈中删除最后一个实例--调用当前小部件的实例
 73             if (get_class($widget) === get_called_class()) {//如果删除的实例的类名和当前调用类的类名相同
 74                 echo $widget->run();//输出小部件的内容
 75                 return $widget;//返回调用类实例
 76             } else {
 77                 throw new InvalidCallException(‘Expecting end() of ‘ . get_class($widget) . ‘, found ‘ . get_called_class());
 78             }
 79         } else {//抛出异常,未找到对应的begin()开始方法
 80             throw new InvalidCallException(‘Unexpected ‘ . get_called_class() . ‘::end() call. A matching begin() is not found.‘);
 81         }
 82     }
 83
 84     /**
 85      * Creates a widget instance and runs it.
 86      * 创建一个widget实例,并运行它
 87      * The widget rendering result is returned by this method.
 88      * widget的渲染结果将被该方法返回
 89      * @param array $config name-value pairs that will be used to initialize the object properties
 90      * @return string the rendering result of the widget.
 91      * @throws \Exception
 92      */
 93     public static function widget($config = [])
 94     {
 95         ob_start();//打开一个输出缓冲区,所有的输出信息不再直接发送到浏览器,而是保存在输出缓冲区里面
 96         ob_implicit_flush(false);//打开或关闭绝对刷新,默认为关闭,打开后ob_implicit_flush(true),
 97           //所谓绝对刷新,即当有输出语句(e.g: echo)被执行时,便把输出直接发送到浏览器,而不再需要调用flush()或等到脚本结束时才输出
 98         try {
 99             /* @var $widget Widget */
100             $config[‘class‘] = get_called_class();//获取调用类的类名
101             $widget = Yii::createObject($config);//实例化调用类
102             $out = $widget->run();//运行widget
103         } catch (\Exception $e) {
104             // close the output buffer opened above if it has not been closed already
105             if (ob_get_level() > 0) {//返回输出缓冲机制的嵌套级别
106                 ob_end_clean();//删除内部缓冲区的内容,关闭缓冲区(不输出)
107             }
108             throw $e;
109         }
110
111         return ob_get_clean() . $out;//返回内部缓冲区的内容,关闭缓冲区
112     }
时间: 2024-12-21 19:59:44

Yii源码阅读笔记(三十)的相关文章

Yii源码阅读笔记(十二)

Action类,控制器中方法的基类: 1 namespace yii\base; 2 3 use Yii; 4 5 /** 6 * Action is the base class for all controller action classes. 7 * Action是所有控制器方法的基类 8 * Action provides a way to reuse action method code. An action method in an Action 9 * class can be

Yii源码阅读笔记(十八)

View中的查找视图文件方法和渲染文件方法 1 /** 2 * Finds the view file based on the given view name. 3 * 通过view文件名查找view文件 4 * @param string $view the view name or the path alias of the view file. Please refer to [[render()]] 5 * on how to specify this parameter. 6 * @

Yii源码阅读笔记(十五)

Model类,集中整个应用的数据和业务逻辑——验证 /** * Returns the attribute labels. * 返回属性的标签 * * Attribute labels are mainly used for display purpose. For example, given an attribute * `firstName`, we can declare a label `First Name` which is more user-friendly and can *

Yii源码阅读笔记(十四)

Model类,集中整个应用的数据和业务逻辑——场景.属性和标签: 1 /** 2 * Returns a list of scenarios and the corresponding active attributes. 3 * An active attribute is one that is subject to validation in the current scenario. 4 * 返回所有场景及与之对应的 active 属性的列表 5 * active 属性是指在默认场景中验

Yii源码阅读笔记(十六)

Model类,集中整个应用的数据和业务逻辑—— /** * Generates a user friendly attribute label based on the give attribute name. * 生成一个对用户友好的属性标签,将属性名中的下划线.破折号.点替换为空格,并且每个单词的首字母大写 * This is done by replacing underscores, dashes and dots with blanks and * changing the first

Yii源码阅读笔记(十)

控制器类,所有控制器的基类,用于调用模型和布局,输出到视图 1 namespace yii\base; 2 3 use Yii; 4 5 /** 6 * Controller is the base class for classes containing controller logic. 7 * 控制器,是所用控制器类的基类 8 * 9 * @property Module[] $modules 只读属性 当前控制器的所有模块 10 * 11 * @property string $rout

Yii源码阅读笔记(十九)

View中渲染view视图文件的前置和后置方法,以及渲染动态内容的方法: 1 /** 2 * @return string|boolean the view file currently being rendered. False if no view file is being rendered. 3 */ 4 public function getViewFile() 5 { 6 return end($this->_viewFiles);//返回[_viewFiles]中的最后一个view

Yii源码阅读笔记 - 日志组件

?使用 Yii框架为开发者提供两个静态方法进行日志记录: Yii::log($message, $level, $category);Yii::trace($message, $category); 两者的区别在于后者依赖于应用开启调试模式,即定义常量YII_DEBUG: defined('YII_DEBUG') or define('YII_DEBUG', true); Yii::log方法的调用需要指定message的level和category.category是格式为“xxx.yyy.z

Yii源码阅读笔记(一)

今天开始阅读yii2的源码,想深入了解一下yii框架的工作原理,同时学习一下优秀的编码规范和风格.在此记录一下阅读中的小心得. 每个框架都有一个入口文件,首先从入口文件开始,yii2的入口文件位于web目录的index.php,用于启动web应用和配置一些路径参数. index.php—— 1 // comment out the following two lines when deployed to production 2 defined('YII_DEBUG') or define('Y

Yii源码阅读笔记(三十五)

Container,用于动态地创建.注入依赖单元,映射依赖关系等功能,减少了许多代码量,降低代码耦合程度,提高项目的可维护性. 1 namespace yii\di; 2 3 use ReflectionClass; 4 use Yii; 5 use yii\base\Component; 6 use yii\base\InvalidConfigException; 7 use yii\helpers\ArrayHelper; 8 9 /** 10 * Container implements