Yii源码阅读笔记(三十)

时间:2022-09-10 15:14:08

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

 namespace yii\base;

 use Yii;
 use ReflectionClass;

 /**
  * Widget is the base class for widgets.
  * Widget是所有小部件的基类
  *
  * @property string $id ID of the widget.
  * @property \yii\web\View $view The view object that can be used to render views or view files. Note that the
  * type of this property differs in getter and setter. See [[getView()]] and [[setView()]] for details.
  * @property string $viewPath The directory containing the view files for this widget. This property is
  * read-only.
  *
  * @author Qiang Xue <qiang.xue@gmail.com>
  * @since 2.0
  */
 class Widget extends Component implements ViewContextInterface
 {
     /**
      * @var integer a counter used to generate [[id]] for widgets.
      * @var integer 一个用于生成widget ID的计数器
      * @internal
      */
     public static $counter = 0;
     /**
      * @var string the prefix to the automatically generated widget IDs.
      * @var string widget IDs自动生成的前缀
      * @see getId()
      */
     public static $autoIdPrefix = 'w';
     /**
      * @var Widget[] the widgets that are currently being rendered (not ended). This property
      * is maintained by [[begin()]] and [[end()]] methods.
      * @var 目前正在呈现的小部件
      * @internal
      */
     public static $stack = [];

     /**
      * Begins a widget.
      * 开始一个小部件
      * This method creates an instance of the calling class. It will apply the configuration
      * to the created instance. A matching [[end()]] call should be called later.
      * 该方法将应用配置文件创建调用类的实例,有一个[[end()]]方法相对应
      * @param array $config name-value pairs that will be used to initialize the object properties
      * @return static the newly created widget instance
      */
     public static function begin($config = [])
     {
         $config['class'] = get_called_class();// get_called_class -- 后期静态绑定("Late Static Binding")类的名称
                                               // 就是用那个类调用的这个方法,就返回那个类,返回值中带有 namespace
         /* @var $widget Widget */
         $widget = Yii::createObject($config);//通过类名和传入的配置,实例化调用类
         static::$stack[] = $widget;//将实例放入正在呈现的小部件堆栈中

         return $widget;//返回小部件实例
     }

     /**
      * Ends a widget.
      * 结束一个小部件
      * Note that the rendering result of the widget is directly echoed out.
      * @return static the widget instance that is ended.
      * @throws InvalidCallException if [[begin()]] and [[end()]] calls are not properly nested
      */
     public static function end()
     {
         if (!empty(static::$stack)) {//正在呈现的小部件堆栈中存在调用类实例
             $widget = array_pop(static::$stack);//则从堆栈中删除最后一个实例--调用当前小部件的实例
             if (get_class($widget) === get_called_class()) {//如果删除的实例的类名和当前调用类的类名相同
                 echo $widget->run();//输出小部件的内容
                 return $widget;//返回调用类实例
             } else {
                 throw new InvalidCallException('Expecting end() of ' . get_class($widget) . ', found ' . get_called_class());
             }
         } else {//抛出异常,未找到对应的begin()开始方法
             throw new InvalidCallException('Unexpected ' . get_called_class() . '::end() call. A matching begin() is not found.');
         }
     }

     /**
      * Creates a widget instance and runs it.
      * 创建一个widget实例,并运行它
      * The widget rendering result is returned by this method.
      * widget的渲染结果将被该方法返回
      * @param array $config name-value pairs that will be used to initialize the object properties
      * @return string the rendering result of the widget.
      * @throws \Exception
      */
     public static function widget($config = [])
     {
         ob_start();//打开一个输出缓冲区,所有的输出信息不再直接发送到浏览器,而是保存在输出缓冲区里面
         ob_implicit_flush(false);//打开或关闭绝对刷新,默认为关闭,打开后ob_implicit_flush(true),
           //所谓绝对刷新,即当有输出语句(e.g: echo)被执行时,便把输出直接发送到浏览器,而不再需要调用flush()或等到脚本结束时才输出
         try {
             /* @var $widget Widget */
             $config['class'] = get_called_class();//获取调用类的类名
             $widget = Yii::createObject($config);//实例化调用类
             $out = $widget->run();//运行widget
         } catch (\Exception $e) {
             // close the output buffer opened above if it has not been closed already
             if (ob_get_level() > 0) {//返回输出缓冲机制的嵌套级别
                 ob_end_clean();//删除内部缓冲区的内容,关闭缓冲区(不输出)
             }
             throw $e;
         }

         return ob_get_clean() . $out;//返回内部缓冲区的内容,关闭缓冲区
     }

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

  1. Yii源码阅读笔记(十八)

    View中的查找视图文件方法和渲染文件方法 /** * Finds the view file based on the given view name. * 通过view文件名查找view文件 * ...

  2. Yii源码阅读笔记(十六)

    Model类,集中整个应用的数据和业务逻辑—— /** * Generates a user friendly attribute label based on the give attribute ...

  3. Yii源码阅读笔记(十五)

    Model类,集中整个应用的数据和业务逻辑——验证 /** * Returns the attribute labels. * 返回属性的标签 * * Attribute labels are mai ...

  4. Yii源码阅读笔记(十四)

    Model类,集中整个应用的数据和业务逻辑——场景.属性和标签: /** * Returns a list of scenarios and the corresponding active attr ...

  5. Yii源码阅读笔记(十二)

    Action类,控制器中方法的基类: namespace yii\base; use Yii; /** * Action is the base class for all controller ac ...

  6. Yii源码阅读笔记(十)

    控制器类,所有控制器的基类,用于调用模型和布局,输出到视图 namespace yii\base; use Yii; /** * Controller is the base class for cl ...

  7. Yii源码阅读笔记(十九)

    View中渲染view视图文件的前置和后置方法,以及渲染动态内容的方法: /** * @return string|boolean the view file currently being rend ...

  8. Yii源码阅读笔记(一)

    今天开始阅读yii2的源码,想深入了解一下yii框架的工作原理,同时学习一下优秀的编码规范和风格.在此记录一下阅读中的小心得. 每个框架都有一个入口文件,首先从入口文件开始,yii2的入口文件位于we ...

  9. Werkzeug源码阅读笔记&lpar;三&rpar;

    这次主要讲下werkzeug中的Local. 源码在werkzeug/local.py Thread Local 在Python中,状态是保存在对象中.Thread Local是一种特殊的对象,它是对 ...

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

    Container,用于动态地创建.注入依赖单元,映射依赖关系等功能,减少了许多代码量,降低代码耦合程度,提高项目的可维护性. namespace yii\di; use ReflectionClas ...

随机推荐

  1. android avd sdk root

    网上的方式都失败了... 网上的方式据说是 用于 2.0 左右版本的. 而我们现在主流都用的是  4.0 以上的. 这个http://quantoubao.blog.163.com/blog/stat ...

  2. 免费 PSD 素材:25个全新的界面设计资源

    在这篇文章中,我们给大家收集了25套全新的 UI 设计素材.这些来自优秀设计师的 PSD 源文件素材让其它的设计师们在设计用户界面原型的时候能够非常便利. 网站用户界面,移动应用程序用户界面和对设计师 ...

  3. BZOJ1367——&lbrack;Baltic2004&rsqb;sequence

    1.题目大意:给一个序列t,然后求一个序列z,使得$|z1-t1|+|z2-t2|+...+|zn-tn|$的值最小,我们只需要求出这个值就可以了,并且z序列是递增的 2.分析:这道题z序列是递增的, ...

  4. HDU 4503 湫湫系列故事——植树节&lpar;单色三角形&rpar;

    题目链接 #include <cstdio> using namespace std; int main() { int n,sum,a,t,i; scanf("%d" ...

  5. python 元类与定制元类

    1:元类 元类:类的创建与管理者 所有类的元类是type class a: pass print(type(a)) 结果:<class 'type'> 2:定制元类 类的实例化过程:(可看 ...

  6. FTS下载地址

    http://download.microsoft.com/download/5/2/e/52e22b90-2ba7-427b-9ea4-604d3b37a2e7/vs2012_tfs_chs.iso

  7. 【转】Android内存机制分析2——分析APP内存使用情况

    上面一篇文章说了Android应用运行在dalvik里面分配的堆和栈内存区别,以及程序中什么代码会在哪里运行.今天主要是讲解一下Android里面如何分析我们程序内存使用情况.以便后续可以分析我们程序 ...

  8. oracle&lowbar;单向函数&lowbar;数字化功能

    oracle_单向函数_数字化功能 1.abs(x)   为了获得x绝对值 2.ceil(x)   用于获得大于或等于x的最小整数. 3.floor(x)   用于获得小于或等于x 4.mod(x,y ...

  9. 软件测试人员在工作中如何运用Linux

    从事过软件测试的小伙们就会明白会使用Linux是多么重要的一件事,工作时需要用到,面试时会被问到,简历中需要写到. 对于软件测试人员来说,不需要你多么熟练使用Linux所有命令,也不需要你对Linux ...

  10. 安装mongo php拓展

    下载php_mongo.dll文件 下载地址:https://s3.amazonaws.com/drivers.mongodb.org/php/index.html(注意对应版本及是否线程安全)需要注 ...