yii源码分析1,yii源码分析
yii源码分析1,yii源码分析
转载请注明:TheViper http://www.cnblogs.com/TheViper/
本文将对yii中的mvc,路由器,filter,组件机制等最主要的部分进行自己的一点浅析,力求说明自己做一个php mvc不是那么的遥不可及,其实是很简单的。
源码基于yii 1.13,为了方便说明,我对其进行了大量的裁剪,不过还是让他保有上面的那些最重要的功能。裁剪下来,其实没有几个文件了,而且每个文件代码最多100多行,避免因为代码太多而懒得看。
所谓的mvc都是让所有请求从一个地方进去,通过对请求,配置的解析,分发到对应的类方法中。
首先当然是入口文件,index.php.
<span>1</span> <?<span>php </span><span>2</span> <span>$app</span> = "app"<span>; </span><span>3</span> <span>$yii</span> = <span>dirname</span> ( <span>__FILE__</span> ) . '/framework/yii.php'<span>; </span><span>4</span> <span>$config</span> = <span>dirname</span> ( <span>__FILE__</span> ) . '/app/protected/config/main.php';<span>//</span><span>载入配置</span> <span>5</span> <span>require_once</span> (<span>$yii</span><span>); </span><span>6</span> Yii::createWebApplication ( <span>$config</span> )->run ();
引入yii.php
<span>1</span> <?<span>php </span><span>2</span> <span>define</span> ( "VIEWS_DIR", "<span>$app</span>/protected/views/"<span> ); </span><span>3</span> <span>define</span> ( "CONTROLLERS_DIR", "<span>$app</span>/protected/controllers/"<span> ); </span><span>4</span> <span>require</span>(<span>dirname</span>(<span>__FILE__</span>).'/YiiBase.php'<span>); </span><span>5</span> <span>class</span> Yii <span>extends</span><span> YiiBase </span><span>6</span> <span>{ </span><span>7</span> }
原来yii是个空的类啊,去看YiiBase.
<span> 1</span> <?<span>php </span><span> 2</span> <span>defined</span> ( 'YII_PATH' ) or <span>define</span> ( 'YII_PATH', <span>dirname</span> ( <span>__FILE__</span><span> ) ); </span><span> 3</span> <span>class</span><span> YiiBase { </span><span> 4</span> <span>public</span> <span>static</span> <span>$classMap</span> = <span>array</span><span> (); </span><span> 5</span> <span>public</span> <span>static</span> <span>$enableIncludePath</span> = <span>true</span><span>; </span><span> 6</span> <span>private</span> <span>static</span> <span>$_aliases</span> = <span>array</span><span> ( </span><span> 7</span> 'system' =><span> YII_PATH </span><span> 8</span> ); <span>//</span><span> alias => path</span> <span> 9</span> <span>private</span> <span>static</span> <span>$_imports</span> = <span>array</span> (); <span>//</span><span> alias => class name or directory</span> <span> 10</span> <span>private</span> <span>static</span> <span>$_includePaths</span>; <span>//</span><span> list of include paths</span> <span> 11</span> <span>private</span> <span>static</span> <span>$_app</span><span>; </span><span> 12</span> <span>private</span> <span>static</span> <span>$_logger</span><span>; </span><span> 13</span> <span>public</span> <span>static</span> <span>function</span> createWebApplication(<span>$config</span> = <span>null</span><span>) { </span><span> 14</span> <span>return</span> self::createApplication ( 'CWebApplication', <span>$config</span><span> ); </span><span> 15</span> <span> } </span><span> 16</span> <span>public</span> <span>static</span> <span>function</span> createApplication(<span>$class</span>, <span>$config</span> = <span>null</span><span>) { </span><span> 17</span> <span>return</span> <span>new</span> <span>$class</span> ( <span>$config</span><span> ); </span><span> 18</span> <span> } </span><span> 19</span> <span>public</span> <span>static</span> <span>function</span><span> app() { </span><span> 20</span> <span>return</span> self::<span>$_app</span><span>; </span><span> 21</span> <span> } </span><span> 22</span> <span>//</span><span>别名路径</span> <span> 23</span> <span>public</span> <span>static</span> <span>function</span> getPathOfAlias(<span>$alias</span><span>) { </span><span> 24</span> <span>if</span> (<span>isset</span> ( self::<span>$_aliases</span> [<span>$alias</span><span>] )) </span><span> 25</span> <span>return</span> self::<span>$_aliases</span> [<span>$alias</span><span>]; </span><span> 26</span> <span>elseif</span> ((<span>$pos</span> = <span>strpos</span> ( <span>$alias</span>, '.' )) !== <span>false</span><span>) { </span><span> 27</span> <span>$rootAlias</span> = <span>substr</span> ( <span>$alias</span>, 0, <span>$pos</span><span> ); </span><span> 28</span> <span>if</span> (<span>isset</span> ( self::<span>$_aliases</span> [<span>$rootAlias</span><span>] )) </span><span> 29</span> <span>return</span> self::<span>$_aliases</span> [<span>$alias</span>] = <span>rtrim</span> ( self::<span>$_aliases</span> [<span>$rootAlias</span>] . DIRECTORY_SEPARATOR . <span>str_replace</span> ( '.', DIRECTORY_SEPARATOR, <span>substr</span> ( <span>$alias</span>, <span>$pos</span> + 1 ) ), '*' .<span> DIRECTORY_SEPARATOR ); </span><span> 30</span> <span> } </span><span> 31</span> <span>return</span> <span>false</span><span>; </span><span> 32</span> <span> } </span><span> 33</span> <span>public</span> <span>static</span> <span>function</span> setPathOfAlias(<span>$alias</span>, <span>$path</span><span>) { </span><span> 34</span> <span>if</span> (<span>empty</span> ( <span>$path</span><span> )) </span><span> 35</span> <span>unset</span> ( self::<span>$_aliases</span> [<span>$alias</span><span>] ); </span><span> 36</span> <span>else</span> <span> 37</span> self::<span>$_aliases</span> [<span>$alias</span>] = <span>rtrim</span> ( <span>$path</span>, '\\/'<span> ); </span><span> 38</span> <span> } </span><span> 39</span> <span>public</span> <span>static</span> <span>function</span> setApplication(<span>$app</span><span>) { </span><span> 40</span> <span>if</span> (self::<span>$_app</span> === <span>null</span> || <span>$app</span> === <span>null</span><span>) </span><span> 41</span> self::<span>$_app</span> = <span>$app</span><span>; </span><span> 42</span> <span> } </span><span> 43</span> <span>public</span> <span>static</span> <span>function</span> import(<span>$alias</span>, <span>$forceInclude</span> = <span>false</span><span>) { </span><span> 44</span> <span>if</span> (<span>isset</span> ( self::<span>$_imports</span> [<span>$alias</span>] )) <span>//</span><span> previously imported</span> <span> 45</span> <span>return</span> self::<span>$_imports</span> [<span>$alias</span><span>]; </span><span> 46</span> <span> 47</span> <span>if</span> (<span>class_exists</span> ( <span>$alias</span>, <span>false</span> ) || <span>interface_exists</span> ( <span>$alias</span>, <span>false</span><span> )) </span><span> 48</span> <span>return</span> self::<span>$_imports</span> [<span>$alias</span>] = <span>$alias</span><span>; </span><span> 49</span> <span>if</span> ((<span>$pos</span> = <span>strrpos</span> ( <span>$alias</span>, '.' )) === <span>false</span>) <span>//</span><span> a simple class name</span> <span> 50</span> <span> { </span><span> 51</span> <span>//</span><span> try to autoload the class with an autoloader if $forceInclude is true</span> <span> 52</span> <span>if</span> (<span>$forceInclude</span> && (Yii::autoload ( <span>$alias</span>, <span>true</span> ) || <span>class_exists</span> ( <span>$alias</span>, <span>true</span><span> ))) </span><span> 53</span> self::<span>$_imports</span> [<span>$alias</span>] = <span>$alias</span><span>; </span><span> 54</span> <span>return</span> <span>$alias</span><span>; </span><span> 55</span> <span> } </span><span> 56</span> <span> 57</span> <span>$className</span> = ( <span>string</span> ) <span>substr</span> ( <span>$alias</span>, <span>$pos</span> + 1<span> ); </span><span> 58</span> <span>$isClass</span> = <span>$className</span> !== '*'<span>; </span><span> 59</span> <span> 60</span> <span>if</span> (<span>$isClass</span> && (<span>class_exists</span> ( <span>$className</span>, <span>false</span> ) || <span>interface_exists</span> ( <span>$className</span>, <span>false</span><span> ))) </span><span> 61</span> <span>return</span> self::<span>$_imports</span> [<span>$alias</span>] = <span>$className</span><span>; </span><span> 62</span> <span> 63</span> <span>if</span> ((<span>$path</span> = self::getPathOfAlias ( <span>$alias</span> )) !== <span>false</span><span>) { </span><span> 64</span> <span>if</span> (<span>$isClass</span><span>) { </span><span> 65</span> <span>if</span> (<span>$forceInclude</span><span>) { </span><span> 66</span> <span>if</span> (<span>is_file</span> ( <span>$path</span> . '.php'<span> )) </span><span> 67</span> <span>require</span> (<span>$path</span> . '.php'<span>); </span><span> 68</span> <span>else</span> <span> 69</span> <span>throw</span> <span>new</span> CException ( Yii::t ( 'yii', 'Alias "{alias}" is invalid. Make sure it points to an existing PHP file and the file is readable.', <span>array</span><span> ( </span><span> 70</span> '{alias}' => <span>$alias</span> <span> 71</span> <span> ) ) ); </span><span> 72</span> self::<span>$_imports</span> [<span>$alias</span>] = <span>$className</span><span>; </span><span> 73</span> } <span>else</span> <span> 74</span> self::<span>$classMap</span> [<span>$className</span>] = <span>$path</span> . '.php'<span>; </span><span> 75</span> <span>return</span> <span>$className</span><span>; </span><span> 76</span> } <span>else</span> <span>//</span><span> a directory</span> <span> 77</span> <span> { </span><span> 78</span> <span>if</span> (self::<span>$_includePaths</span> === <span>null</span><span>) { </span><span> 79</span> self::<span>$_includePaths</span> = <span>array_unique</span> ( <span>explode</span> ( PATH_SEPARATOR, <span>get_include_path</span><span> () ) ); </span><span> 80</span> <span>if</span> ((<span>$pos</span> = <span>array_search</span> ( '.', self::<span>$_includePaths</span>, <span>true</span> )) !== <span>false</span><span>) </span><span> 81</span> <span>unset</span> ( self::<span>$_includePaths</span> [<span>$pos</span><span>] ); </span><span> 82</span> <span> } </span><span> 83</span> <span> 84</span> <span>array_unshift</span> ( self::<span>$_includePaths</span>, <span>$path</span><span> ); </span><span> 85</span> <span> 86</span> <span>if</span> (self::<span>$enableIncludePath</span> && <span>set_include_path</span> ( '.' . PATH_SEPARATOR . <span>implode</span> ( PATH_SEPARATOR, self::<span>$_includePaths</span> ) ) === <span>false</span><span>) </span><span> 87</span> self::<span>$enableIncludePath</span> = <span>false</span><span>; </span><span> 88</span> <span> 89</span> <span>return</span> self::<span>$_imports</span> [<span>$alias</span>] = <span>$path</span><span>; </span><span> 90</span> <span> } </span><span> 91</span> <span> } </span><span> 92</span> <span> } </span><span> 93</span> <span>//</span><span>创建组件实例</span> <span> 94</span> <span>public</span> <span>static</span> <span>function</span> createComponent(<span>$config</span><span>) { </span><span> 95</span> <span>if</span> (<span>is_string</span> ( <span>$config</span><span> )) { </span><span> 96</span> <span>$type</span> = <span>$config</span><span>; </span><span> 97</span> <span>$config</span> = <span>array</span><span> (); </span><span> 98</span> } <span>elseif</span> (<span>isset</span> ( <span>$config</span> ['class'<span>] )) { </span><span> 99</span> <span>$type</span> = <span>$config</span> ['class'<span>]; </span><span>100</span> <span>unset</span> ( <span>$config</span> ['class'<span>] ); </span><span>101</span> <span> } </span><span>102</span> <span>if</span> (! <span>class_exists</span> ( <span>$type</span>, <span>false</span><span> )) { </span><span>103</span> <span>$type</span> = Yii::import ( <span>$type</span>, <span>true</span><span> ); </span><span>104</span> <span> } </span><span>105</span> <span>if</span> ((<span>$n</span> = <span>func_num_args</span> ()) > 1<span>) { </span><span>106</span> <span>$args</span> = <span>func_get_args</span><span> (); </span><span>107</span> <span>if</span> (<span>$n</span> === 2<span>) </span><span>108</span> <span>$object</span> = <span>new</span> <span>$type</span> ( <span>$args</span> [1<span>] ); </span><span>109</span> <span>elseif</span> (<span>$n</span> === 3<span>) </span><span>110</span> <span>$object</span> = <span>new</span> <span>$type</span> ( <span>$args</span> [1], <span>$args</span> [2<span>] ); </span><span>111</span> <span>elseif</span> (<span>$n</span> === 4<span>) </span><span>112</span> <span>$object</span> = <span>new</span> <span>$type</span> ( <span>$args</span> [1], <span>$args</span> [2], <span>$args</span> [3<span>] ); </span><span>113</span> <span>else</span><span> { </span><span>114</span> <span>unset</span> ( <span>$args</span> [0<span>] ); </span><span>115</span> <span>$class</span> = <span>new</span> ReflectionClass ( <span>$type</span><span> ); </span><span>116</span> <span>//</span><span> Note: ReflectionClass::newInstanceArgs() is available for PHP 5.1.3+ </span><span>117</span> <span> // $object=$class->newInstanceArgs($args);</span> <span>118</span> <span>$object</span> = <span>call_user_func_array</span> ( <span>array</span><span> ( </span><span>119</span> <span>$class</span>, <span>120</span> 'newInstance' <span>121</span> ), <span>$args</span><span> ); </span><span>122</span> <span> } </span><span>123</span> } <span>else</span> <span>124</span> <span>$object</span> = <span>new</span> <span>$type</span><span> (); </span><span>125</span> <span>foreach</span> ( <span>$config</span> <span>as</span> <span>$key</span> => <span>$value</span><span> ) </span><span>126</span> <span>$object</span>-><span>$key</span> = <span>$value</span><span>; </span><span>127</span> <span>128</span> <span>return</span> <span>$object</span><span>; </span><span>129</span> <span> } </span><span>130</span> <span>//</span><span>按需加载相应的php</span> <span>131</span> <span>public</span> <span>static</span> <span>function</span> autoload(<span>$className</span><span>) { </span><span>132</span> <span>include</span> self::<span>$_coreClasses</span> [<span>$className</span><span>]; </span><span>133</span> <span> } </span><span>134</span> <span>private</span> <span>static</span> <span>$_coreClasses</span> = <span>array</span><span> ( </span><span>135</span> 'CApplication' => '/base/CApplication.php', <span>136</span> 'CModule' => '/base/CModule.php', <span>137</span> 'CWebApplication' => '/base/CWebApplication.php', <span>138</span> 'CUrlManager' => 'CUrlManager.php', <span>139</span> 'CComponent' => '/base/CComponent.php' <span>140</span> , 'CUrlRule' => 'CUrlRule.php', <span>141</span> 'CController' => 'CController.php', <span>142</span> 'CInlineAction' => '/actions/CInlineAction.php', <span>143</span> 'CAction' => '/actions/CAction.php', <span>144</span> 'CFilterChain' => '/filters/CFilterChain.php', <span>145</span> 'CFilter' => '/filters/CFilter.php', <span>146</span> 'CList' => '/collections/CList.php', <span>147</span> 'CHttpRequest' => 'CHttpRequest.php', <span>148</span> 'CDb' => 'CDb.php', <span>149</span> 'CInlineFilter' => 'filters/CInlineFilter.php' <span>150</span> <span> ); </span><span>151</span> <span>} </span><span>152</span> <span>153</span> spl_autoload_register ( <span>array</span><span> ( </span><span>154</span> 'YiiBase', <span>155</span> 'autoload' <span>156</span> ) );
看似很多,其实就三个地方注意下就可以了
1.spl_autoload_register,用这个就可以实现传说中的按需加载相应的php了,坑爹啊。
2.createComponent($config)这个方法是yii组件调用的核心。在配置中注册的所有组件都是通过它获取组件类的实例的。比如配置:
<span> 1</span> <?<span>php </span><span> 2</span> <span>return</span> <span>array</span><span> ( </span><span> 3</span> 'basePath' => <span>dirname</span> ( <span>__FILE__</span> ) . DIRECTORY_SEPARATOR . '..', <span> 4</span> <span> 5</span> 'import' => <span>array</span><span> ( </span><span> 6</span> 'application.util.*' <span> 7</span> ), <span> 8</span> <span> 9</span> 'components' => <span>array</span><span> ( </span><span>10</span> 'db' => <span>array</span><span> ( </span><span>11</span> 'class' => 'CDb', <span>12</span> 'driver' => 'mysql', <span>13</span> 'hostname' => 'localhost', <span>14</span> 'username' => 'root', <span>15</span> 'password' => '', <span>16</span> 'database' => 'youtube' <span>17</span> ), <span>18</span> 'urlManager' => <span>array</span><span> ( </span><span>19</span> 'urlFormat' => 'path', <span>20</span> 'rules' => <span>array</span><span> ( </span><span>21</span> 'comment_reply/<a:\d+>/<ci:\d+>' => 'reply/load_comment_reply', <span>22</span> 'b/<id:\d+>' => <span>array</span><span> ( </span><span>23</span> 'video/broadcast', <span>24</span> 'urlSuffix' => '.html' <span>25</span> ), <span>26</span> 'c/<list_start:\d+>' => 'video/list_more_video', <span>27</span> 'u/reg' => 'user/reg', <span>28</span> 'v/upload' => 'video/upload_video', <span>29</span> 'login' => 'user/to_login', <span>30</span> 'show_chanel/<chanel_id:\d+>' => 'show/chanel' , <span>31</span> 'show/<show_id:\d+>' => 'show/show', <span>32</span> <span> ) </span><span>33</span> <span> ) </span><span>34</span> <span> ) </span><span>35</span> <span>); </span><span>36</span> ?>
这个文件就返回了个map,里面components中的db,urlManager便是我注册的系统中的组件,里面的array便是组件的参数.
从源码中看到$type = $config ['class'];$object = new $type;就创建了注册的类实例了。
3.import($alias, $forceInclude = false)。作用:导入一个类或一个目录。导入一个类就像包含相应的类文件。 主要区别是导入一个类比较轻巧, 它仅在类文件首次引用时包含。这个也是yii的一个核心优化点。
这个在上面createComponent($config)中有用到,
if (!class_exists ( $type, false )) {
$type = Yii::import ( $type, true );
}
如果$type类没有定义,就去导入。有些组件,核心在yii中多次create调用,这样就保证了仅在类文件首次引用时导入。
下面分析index.php中Yii::createWebApplication ( $config )的调用过程。
这个调用是去了CWebApplication。
<span> 1</span> <?<span>php </span><span> 2</span> <span>class</span> CWebApplication <span>extends</span><span> CApplication { </span><span> 3</span> <span>public</span> <span>$controllerNamespace</span><span>; </span><span> 4</span> <span>private</span> <span>$_controllerPath</span><span>; </span><span> 5</span> <span>private</span> <span>$_viewPath</span><span>; </span><span> 6</span> <span>private</span> <span>$_systemViewPath</span><span>; </span><span> 7</span> <span>private</span> <span>$_controller</span><span>; </span><span> 8</span> <span>public</span> <span>$controllerMap</span>=<span>array</span><span>(); </span><span> 9</span> <span>public</span> <span>function</span> processRequest() {<span>//</span><span>开始执行请求 </span><span>10</span> <span> //获取urlManager组件,解析请求,得到controller/action这种格式的string, </span><span>11</span> <span> //并且将隐藏参数与请求的参数一一对应,匹配起来,写入$_REQUEST中</span> <span>12</span> <span>$route</span> = <span>$this</span>->getUrlManager ()->parseUrl (<span>$this</span>-><span>getRequest()); </span><span>13</span> <span>$this</span>->runController ( <span>$route</span><span> ); </span><span>14</span> <span> } </span><span>15</span> <span>public</span> <span>function</span> getRequest() {<span>//</span><span>获取request组件</span> <span>16</span> <span>return</span> <span>$this</span>->getComponent ( 'request'<span> ); </span><span>17</span> <span> } </span><span>18</span> <span>protected</span> <span>function</span> registerCoreComponents() {<span>//</span><span>注册核心组件</span> <span>19</span> parent::<span>registerCoreComponents (); </span><span>20</span> <span> } </span><span>21</span> <span>//</span><span>执行contronller</span> <span>22</span> <span>public</span> <span>function</span> runController(<span>$route</span><span>) { </span><span>23</span> <span>if</span> ((<span>$ca</span> = <span>$this</span>->createController ( <span>$route</span> )) !== <span>null</span><span>) { </span><span>24</span> <span>list</span> ( <span>$controller</span>, <span>$actionID</span> ) = <span>$ca</span><span>; </span><span>25</span> <span>$oldController</span> = <span>$this</span>-><span>_controller; </span><span>26</span> <span>$this</span>->_controller = <span>$controller</span><span>; </span><span>27</span> <span>$controller</span>->init ();<span>//</span><span>钩子,在执行action方法前调用,子类去实现</span> <span>28</span> <span>$controller</span>->run ( <span>$actionID</span> );<span>//</span><span>开始转入controller类中action方法的执行</span> <span>29</span> <span>$this</span>->_controller = <span>$oldController</span><span>; </span><span>30</span> <span> } </span><span>31</span> <span> } </span><span>32</span> <span>//</span><span>创建controller类实例,从controller/action这种格式的string中解析出$controller, $actionID </span> <span>33</span> <span>public</span> <span>function</span> createController(<span>$route</span>, <span>$owner</span> = <span>null</span><span>) { </span><span>34</span> <span>if</span> (<span>$owner</span> === <span>null</span><span>) </span><span>35</span> <span>$owner</span> = <span>$this</span><span>; </span><span>36</span> <span>if</span> ((<span>$route</span> = <span>trim</span> ( <span>$route</span>, '/' )) === ''<span>) </span><span>37</span> <span>$route</span> = <span>$owner</span>-><span>defaultController; </span><span>38</span> <span>39</span> <span>$route</span> .= '/'<span>; </span><span>40</span> <span>while</span> ( (<span>$pos</span> = <span>strpos</span> ( <span>$route</span>, '/' )) !== <span>false</span><span> ) { </span><span>41</span> <span>$id</span> = <span>substr</span> ( <span>$route</span>, 0, <span>$pos</span><span> ); </span><span>42</span> <span>if</span> (! <span>preg_match</span> ( '/^\w+$/', <span>$id</span><span> )) </span><span>43</span> <span>return</span> <span>null</span><span>; </span><span>44</span> <span>$id</span> = <span>strtolower</span> ( <span>$id</span><span> ); </span><span>45</span> <span>$route</span> = ( <span>string</span> ) <span>substr</span> ( <span>$route</span>, <span>$pos</span> + 1<span> ); </span><span>46</span> <span>if</span> (! <span>isset</span> ( <span>$basePath</span> )) <span>//</span><span> first segment</span> <span>47</span> <span> { </span><span>48</span> <span>$basePath</span> = <span>$owner</span>-><span>getControllerPath (); </span><span>49</span> <span>$controllerID</span> = ''<span>; </span><span>50</span> } <span>else</span><span> { </span><span>51</span> <span>$controllerID</span> .= '/'<span>; </span><span>52</span> <span> } </span><span>53</span> <span>$className</span> = <span>ucfirst</span> ( <span>$id</span> ) . 'Controller'<span>; </span><span>54</span> <span>$classFile</span> = <span>$basePath</span> . DIRECTORY_SEPARATOR . <span>$className</span> . '.php'<span>; </span><span>55</span> <span>56</span> <span>if</span> (<span>is_file</span> ( <span>$classFile</span><span> )) { </span><span>57</span> <span>if</span> (! <span>class_exists</span> ( <span>$className</span>, <span>false</span><span> )) </span><span>58</span> <span>require</span> (<span>$classFile</span><span>); </span><span>59</span> <span>if</span> (<span>class_exists</span> ( <span>$className</span>, <span>false</span> ) && <span>is_subclass_of</span> ( <span>$className</span>, 'CController'<span> )) { </span><span>60</span> <span>$id</span> [0] = <span>strtolower</span> ( <span>$id</span> [0<span>] ); </span><span>61</span> <span>return</span> <span>array</span><span> ( </span><span>62</span> <span>new</span> <span>$className</span> ( <span>$controllerID</span> . <span>$id</span>, <span>$owner</span> === <span>$this</span> ? <span>null</span> : <span>$owner</span> ), <span>63</span> <span>$this</span>->parseActionParams ( <span>$route</span><span> ) </span><span>64</span> <span> ); </span><span>65</span> <span> } </span><span>66</span> <span>return</span> <span>null</span><span>; </span><span>67</span> <span> } </span><span>68</span> <span>$controllerID</span> .= <span>$id</span><span>; </span><span>69</span> <span>$basePath</span> .= DIRECTORY_SEPARATOR . <span>$id</span><span>; </span><span>70</span> <span> } </span><span>71</span> <span> } </span><span>72</span> <span>protected</span> <span>function</span> parseActionParams(<span>$pathInfo</span><span>) { </span><span>73</span> <span>if</span> ((<span>$pos</span> = <span>strpos</span> ( <span>$pathInfo</span>, '/' )) !== <span>false</span><span>) { </span><span>74</span> <span>$manager</span> = <span>$this</span>->getUrlManager ();<span>//</span><span>再次获取urlManager,在上面第一次调用中已经导入。</span> <span>75</span> <span>$manager</span>->parsePathInfo ( ( <span>string</span> ) <span>substr</span> ( <span>$pathInfo</span>, <span>$pos</span> + 1<span> ) ); </span><span>76</span> <span>$actionID</span> = <span>substr</span> ( <span>$pathInfo</span>, 0, <span>$pos</span><span> ); </span><span>77</span> <span>return</span> <span>$manager</span>->caseSensitive ? <span>$actionID</span> : <span>strtolower</span> ( <span>$actionID</span><span> ); </span><span>78</span> } <span>else</span> <span>79</span> <span>return</span> <span>$pathInfo</span><span>; </span><span>80</span> <span> } </span><span>81</span> <span>public</span> <span>function</span><span> getControllerPath() { </span><span>82</span> <span>if</span> (<span>$this</span>->_controllerPath !== <span>null</span><span>) </span><span>83</span> <span>return</span> <span>$this</span>-><span>_controllerPath; </span><span>84</span> <span>else</span> <span>85</span> <span>return</span> <span>$this</span>->_controllerPath = <span>$this</span>->getBasePath () . DIRECTORY_SEPARATOR . 'controllers'<span>; </span><span>86</span> <span> } </span><span>87</span> <span>//</span><span>两个钩子,子类去实现</span> <span>88</span> <span>public</span> <span>function</span> beforeControllerAction(<span>$controller</span>, <span>$action</span><span>) { </span><span>89</span> <span>return</span> <span>true</span><span>; </span><span>90</span> <span> } </span><span>91</span> <span>public</span> <span>function</span> afterControllerAction(<span>$controller</span>, <span>$action</span><span>) { </span><span>92</span> <span> } </span><span>93</span> <span>protected</span> <span>function</span><span> init() { </span><span>94</span> parent::<span>init (); </span><span>95</span> <span> } </span><span>96</span> }
没有构造方法,构造方法在父类CApplication里面。
<span> 1</span> <?<span>php </span><span> 2</span> <span>abstract</span> <span>class</span> CApplication <span>extends</span><span> CModule { </span><span> 3</span> <span>private</span> <span>$_id</span><span>; </span><span> 4</span> <span>private</span> <span>$_basePath</span><span>; </span><span> 5</span> <span>abstract</span> <span>public</span> <span>function</span><span> processRequest(); </span><span> 6</span> <span>public</span> <span>function</span> __construct(<span>$config</span> = <span>null</span><span>) { </span><span> 7</span> <span>if</span> (<span>is_string</span> ( <span>$config</span><span> )) </span><span> 8</span> <span>$config</span> = <span>require</span> (<span>$config</span><span>); </span><span> 9</span> Yii::setApplication ( <span>$this</span> );<span>//</span><span>保存整个app实例</span> <span>10</span> <span>if</span> (<span>isset</span> ( <span>$config</span> ['basePath'<span>] )) { </span><span>11</span> <span>$this</span>->setBasePath ( <span>$config</span> ['basePath'<span>] ); </span><span>12</span> <span>unset</span> ( <span>$config</span> ['basePath'<span>] ); </span><span>13</span> } <span>else</span> <span>14</span> <span>$this</span>->setBasePath ( 'protected'<span> ); </span><span>15</span> <span>//</span><span>设置别名,后面就可以用application表示basePath了</span> <span>16</span> Yii::setPathOfAlias ( 'application', <span>$this</span>-><span>getBasePath () ); </span><span>17</span> <span>//</span><span>钩子,模块 预 初始化时执行,子类实现。不过这时,配置还没有写入框架</span> <span>18</span> <span>$this</span>-><span>preinit (); </span><span>19</span> <span>$this</span>-><span>registerCoreComponents (); </span><span>20</span> <span>//</span><span>父类实现</span> <span>21</span> <span>$this</span>->configure ( <span>$config</span><span> ); </span><span>22</span> <span>//</span><span>加载静态应用组件</span> <span>23</span> <span>$this</span>-><span>preloadComponents (); </span><span>24</span> <span>//</span><span>这才开始初始化模块</span> <span>25</span> <span>$this</span>-><span>init (); </span><span>26</span> <span> } </span><span>27</span> <span>protected</span> <span>function</span><span> registerCoreComponents() { </span><span>28</span> <span>$components</span> = <span>array</span><span> ( </span><span>29</span> 'request' => <span>array</span><span> ( </span><span>30</span> 'class' => 'CHttpRequest' <span>31</span> ), <span>32</span> 'urlManager' => <span>array</span><span> ( </span><span>33</span> 'class' => 'CUrlManager' <span>34</span> <span> ) </span><span>35</span> <span> ); </span><span>36</span> <span>37</span> <span>$this</span>->setComponents ( <span>$components</span> );<span>//</span><span>父类实现</span> <span>38</span> <span> } </span><span>39</span> <span>public</span> <span>function</span><span> run() { </span><span>40</span> <span>$this</span>-><span>processRequest (); </span><span>41</span> <span> } </span><span>42</span> <span>public</span> <span>function</span><span> getId() { </span><span>43</span> <span>if</span> (<span>$this</span>->_id !== <span>null</span><span>) </span><span>44</span> <span>return</span> <span>$this</span>-><span>_id; </span><span>45</span> <span>else</span> <span>46</span> <span>return</span> <span>$this</span>->_id = <span>sprintf</span> ( '%x', <span>crc32</span> ( <span>$this</span>->getBasePath () . <span>$this</span>-><span>name ) ); </span><span>47</span> <span> } </span><span>48</span> <span>public</span> <span>function</span> setId(<span>$id</span><span>) { </span><span>49</span> <span>$this</span>->_id = <span>$id</span><span>; </span><span>50</span> <span> } </span><span>51</span> <span>public</span> <span>function</span><span> getBasePath() { </span><span>52</span> <span>return</span> <span>$this</span>-><span>_basePath; </span><span>53</span> <span> } </span><span>54</span> <span>public</span> <span>function</span> setBasePath(<span>$path</span><span>) { </span><span>55</span> <span>if</span> ((<span>$this</span>->_basePath = <span>realpath</span> ( <span>$path</span> )) === <span>false</span> || ! <span>is_dir</span> ( <span>$this</span>-><span>_basePath )) </span><span>56</span> <span>return</span><span>; </span><span>57</span> <span> } </span><span>58</span> <span>public</span> <span>function</span><span> getDb() { </span><span>59</span> <span>return</span> <span>$this</span>->getComponent ( 'db' );<span>//</span><span>父类实现</span> <span>60</span> <span> } </span><span>61</span> <span>public</span> <span>function</span><span> getUrlManager() { </span><span>62</span> <span>return</span> <span>$this</span>->getComponent ( 'urlManager'<span> ); </span><span>63</span> <span> } </span><span>64</span> <span>public</span> <span>function</span><span> getController() { </span><span>65</span> <span>return</span> <span>null</span><span>; </span><span>66</span> <span> } </span><span>67</span> <span>public</span> <span>function</span> getBaseUrl(<span>$absolute</span> = <span>false</span><span>) { </span><span>68</span> <span>return</span> <span>$this</span>->getRequest ()->getBaseUrl ( <span>$absolute</span><span> ); </span><span>69</span> <span> } </span><span>70</span> }
__construct里面注释写的很详细了,值得注意的是registerCoreComponents ()。前面说了那么多,那么Yii::createWebApplication ( $config )到底是做什么的。
其实最终目的对这个裁剪过的yii而言就是注册核心组件。就这么简单.
setComponents ( $components )在父类CModule里面.
<span> 1</span> <?<span>php </span><span> 2</span> <span>abstract</span> <span>class</span> CModule <span>extends</span><span> CComponent { </span><span> 3</span> <span>public</span> <span>$preload</span> = <span>array</span><span> (); </span><span> 4</span> <span>public</span> <span>$behaviors</span> = <span>array</span><span> (); </span><span> 5</span> <span>private</span> <span>$_id</span><span>; </span><span> 6</span> <span>private</span> <span>$_parentModule</span><span>; </span><span> 7</span> <span>private</span> <span>$_basePath</span><span>; </span><span> 8</span> <span>private</span> <span>$_modulePath</span><span>; </span><span> 9</span> <span>private</span> <span>$_params</span><span>; </span><span>10</span> <span>private</span> <span>$_modules</span> = <span>array</span><span> (); </span><span>11</span> <span>private</span> <span>$_moduleConfig</span> = <span>array</span><span> (); </span><span>12</span> <span>private</span> <span>$_components</span> = <span>array</span><span> (); </span><span>13</span> <span>private</span> <span>$_componentConfig</span> = <span>array</span><span> (); </span><span>14</span> <span>//</span><span>重写是为了方便直接用 application.组件 这种方式直接获取组件</span> <span>15</span> <span>public</span> <span>function</span> __get(<span>$name</span><span>) { </span><span>16</span> <span>if</span> (<span>$this</span>->hasComponent ( <span>$name</span><span> )) </span><span>17</span> <span>return</span> <span>$this</span>->getComponent ( <span>$name</span><span> ); </span><span>18</span> <span>else</span> <span>19</span> <span>return</span> parent::__get ( <span>$name</span><span> ); </span><span>20</span> <span> } </span><span>21</span> <span>public</span> <span>function</span> __isset(<span>$name</span><span>) { </span><span>22</span> <span>if</span> (<span>$this</span>->hasComponent ( <span>$name</span><span> )) </span><span>23</span> <span>return</span> <span>$this</span>->getComponent ( <span>$name</span> ) !== <span>null</span><span>; </span><span>24</span> <span>else</span> <span>25</span> <span>return</span> parent::__isset ( <span>$name</span><span> ); </span><span>26</span> <span> } </span><span>27</span> <span>public</span> <span>function</span> hasComponent(<span>$id</span><span>) { </span><span>28</span> <span>return</span> <span>isset</span> ( <span>$this</span>->_components [<span>$id</span>] ) || <span>isset</span> ( <span>$this</span>->_componentConfig [<span>$id</span><span>] ); </span><span>29</span> <span> } </span><span>30</span> <span>// </span><span>31</span> <span>public</span> <span>function</span> getComponent(<span>$id</span>, <span>$createIfNull</span> = <span>true</span><span>) { </span><span>32</span> <span>if</span> (<span>isset</span> ( <span>$this</span>->_components [<span>$id</span><span>] )) </span><span>33</span> <span>return</span> <span>$this</span>->_components [<span>$id</span><span>]; </span><span>34</span> <span>else</span> <span>if</span> (<span>isset</span> ( <span>$this</span>->_componentConfig [<span>$id</span>] ) && <span>$createIfNull</span><span>) { </span><span>35</span> <span>$config</span> = <span>$this</span>->_componentConfig [<span>$id</span><span>]; </span><span>36</span> <span>$component</span> = Yii::createComponent ( <span>$config</span> );<span>//</span><span>YiiBase,返回组件实例</span> <span>37</span> <span>$component</span>->init ();<span>//</span><span>钩子,调用子类重写的init方法 </span><span>38</span> <span> //将组件写入数组保存,并返回</span> <span>39</span> <span>return</span> <span>$this</span>->_components [<span>$id</span>] = <span>$component</span><span>; </span><span>40</span> <span> } </span><span>41</span> <span> } </span><span>42</span> <span>public</span> <span>function</span> setComponent(<span>$id</span>, <span>$component</span>, <span>$merge</span> = <span>true</span><span>) { </span><span>43</span> <span>//</span><span>组件写入数组保存</span> <span>44</span> <span>if</span> (<span>isset</span> ( <span>$this</span>->_componentConfig [<span>$id</span>] ) && <span>$merge</span><span>) { </span><span>45</span> <span>46</span> <span>$this</span>->_componentConfig [<span>$id</span>] = self::mergeArray ( <span>$this</span>->_componentConfig [<span>$id</span>], <span>$component</span><span> ); </span><span>47</span> } <span>else</span><span> { </span><span>48</span> <span>49</span> <span>$this</span>->_componentConfig [<span>$id</span>] = <span>$component</span><span>; </span><span>50</span> <span> } </span><span>51</span> <span> } </span><span>52</span> <span>public</span> <span>static</span> <span>function</span> mergeArray(<span>$a</span>, <span>$b</span><span>) { </span><span>53</span> <span>$args</span> = <span>func_get_args</span><span> (); </span><span>54</span> <span>$res</span> = <span>array_shift</span> ( <span>$args</span><span> ); </span><span>55</span> <span>while</span> ( ! <span>empty</span> ( <span>$args</span><span> ) ) { </span><span>56</span> <span>$next</span> = <span>array_shift</span> ( <span>$args</span><span> ); </span><span>57</span> <span>foreach</span> ( <span>$next</span> <span>as</span> <span>$k</span> => <span>$v</span><span> ) { </span><span>58</span> <span>if</span> (<span>is_integer</span> ( <span>$k</span><span> )) </span><span>59</span> <span>isset</span> ( <span>$res</span> [<span>$k</span>] ) ? <span>$res</span> [] = <span>$v</span> : <span>$res</span> [<span>$k</span>] = <span>$v</span><span>; </span><span>60</span> <span>elseif</span> (<span>is_array</span> ( <span>$v</span> ) && <span>isset</span> ( <span>$res</span> [<span>$k</span>] ) && <span>is_array</span> ( <span>$res</span> [<span>$k</span><span>] )) </span><span>61</span> <span>$res</span> [<span>$k</span>] = self::mergeArray ( <span>$res</span> [<span>$k</span>], <span>$v</span><span> ); </span><span>62</span> <span>else</span> <span>63</span> <span>$res</span> [<span>$k</span>] = <span>$v</span><span>; </span><span>64</span> <span> } </span><span>65</span> <span> } </span><span>66</span> <span>return</span> <span>$res</span><span>; </span><span>67</span> <span> } </span><span>68</span> <span>public</span> <span>function</span> setComponents(<span>$components</span>, <span>$merge</span> = <span>true</span><span>) { </span><span>69</span> <span>foreach</span> ( <span>$components</span> <span>as</span> <span>$id</span> => <span>$component</span><span> ) </span><span>70</span> <span>$this</span>->setComponent ( <span>$id</span>, <span>$component</span>, <span>$merge</span><span> ); </span><span>71</span> <span> } </span><span>72</span> <span>//</span><span>子类CApplication调用,用来为模块指定配置</span> <span>73</span> <span>public</span> <span>function</span> configure(<span>$config</span><span>) { </span><span>74</span> <span>if</span> (<span>is_array</span> ( <span>$config</span><span> )) { </span><span>75</span> <span>foreach</span> ( <span>$config</span> <span>as</span> <span>$key</span> => <span>$value</span><span> ) </span><span>76</span> <span>$this</span>-><span>$key</span> = <span>$value</span><span>; </span><span>77</span> <span> } </span><span>78</span> <span> } </span><span>79</span> <span>protected</span> <span>function</span><span> preloadComponents() { </span><span>80</span> <span>foreach</span> ( <span>$this</span>->preload <span>as</span> <span>$id</span><span> ) </span><span>81</span> <span>$this</span>->getComponent ( <span>$id</span><span> ); </span><span>82</span> <span> } </span><span>83</span> <span>//</span><span>又是两个钩子</span> <span>84</span> <span>protected</span> <span>function</span><span> preinit() { </span><span>85</span> <span> } </span><span>86</span> <span>protected</span> <span>function</span><span> init() { </span><span>87</span> <span> } </span><span>88</span> }
看到所谓的注册组件就是写入数组保存,getComponent()的时候就是用前面讲到的YiiBase里面的createComponent($config)返回组件实例。就这么简单。
而CApplication里面的什么getDb(),getUrlManager()也是在调用getComponent()。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제









클라우드 컴퓨팅 기술이 지속적으로 발전하면서 데이터 백업은 모든 기업이 반드시 해야 할 일이 되었습니다. 이러한 맥락에서 가용성이 높은 클라우드 백업 시스템을 개발하는 것이 특히 중요합니다. PHP 프레임워크 Yii는 개발자가 고성능 웹 애플리케이션을 빠르게 구축하는 데 도움이 되는 강력한 프레임워크입니다. 다음은 Yii 프레임워크를 사용하여 고가용성 클라우드 백업 시스템을 개발하는 방법을 소개합니다. 데이터베이스 모델 설계 Yii 프레임워크에서 데이터베이스 모델은 매우 중요한 부분입니다. 데이터 백업 시스템에는 많은 테이블과 관계가 필요하기 때문에

현재 정보화 시대에는 빅데이터, 인공지능, 클라우드 컴퓨팅 등의 기술이 주요 기업의 화두가 되었습니다. 이러한 기술들 중에서 고성능 그래픽 처리 기술로서 그래픽 카드 렌더링 기술이 점점 주목을 받고 있다. 그래픽 카드 렌더링 기술은 게임 개발, 영화 및 TV 특수 효과, 엔지니어링 모델링 및 기타 분야에서 널리 사용됩니다. 개발자에게 자신의 프로젝트에 적합한 프레임워크를 선택하는 것은 매우 중요한 결정입니다. 현재 언어 중에서 PHP는 Yii2, Ph와 같은 뛰어난 PHP 프레임워크 중 매우 역동적인 언어입니다.

인터넷이 계속 발전함에 따라 웹 애플리케이션 개발에 대한 수요도 점점 높아지고 있습니다. 개발자의 경우 애플리케이션 개발에는 개발 효율성을 향상시킬 수 있는 안정적이고 효율적이며 강력한 프레임워크가 필요합니다. Yii는 풍부한 기능과 우수한 성능을 제공하는 선도적인 고성능 PHP 프레임워크입니다. Yii3은 Yii2를 기반으로 성능과 코드 품질을 더욱 최적화하는 Yii 프레임워크의 차세대 버전입니다. 이번 글에서는 Yii3 프레임워크를 사용하여 PHP 애플리케이션을 개발하는 방법을 소개하겠습니다.

Yii 프레임워크는 웹 애플리케이션 개발 프로세스를 단순화하기 위한 다양한 도구와 구성 요소를 제공하는 오픈 소스 PHP 웹 애플리케이션 프레임워크입니다. 데이터 쿼리는 중요한 구성 요소 중 하나입니다. Yii 프레임워크에서는 SQL과 유사한 구문을 사용하여 데이터베이스에 액세스하여 데이터를 효율적으로 쿼리하고 조작할 수 있습니다. Yii 프레임워크의 쿼리 빌더에는 주로 ActiveRecord 쿼리, QueryBuilder 쿼리, 명령 쿼리 및 원본 SQL 쿼리 유형이 포함됩니다.

웹 애플리케이션에 대한 수요가 계속 증가함에 따라 개발자는 개발 프레임워크를 선택할 때 점점 더 많은 선택권을 갖게 되었습니다. Symfony와 Yii2는 두 가지 인기 있는 PHP 프레임워크입니다. 둘 다 강력한 기능과 성능을 갖추고 있지만 대규모 웹 애플리케이션을 개발해야 하는 경우 어떤 프레임워크가 더 적합합니까? 다음으로 더 나은 선택을 하실 수 있도록 Symphony와 Yii2의 비교 분석을 진행하겠습니다. 기본 개요 Symphony는 PHP로 작성된 오픈 소스 웹 애플리케이션 프레임워크이며 다음을 기반으로 합니다.

Yii 프레임워크: 이 기사에서는 객체를 배열로 변환하거나 json 형식으로 직접 출력하는 Yii의 방법을 소개합니다. 이는 특정 참조 가치가 있으며 모든 사람에게 도움이 되기를 바랍니다.

"Yii가 무엇인가요?"라고 묻는다면 Yii의 이점을 검토하고 2014년 10월에 출시된 Yii 2.0의 새로운 기능을 간략하게 설명하는 이전 튜토리얼인 Yii 프레임워크 소개를 확인하세요. 흠> 이번 Yii2 프로그래밍 시리즈에서는 Yii2PHP 프레임워크를 사용하는 방법을 독자들에게 안내하겠습니다. 오늘 튜토리얼에서는 Yii의 콘솔 기능을 활용하여 크론 작업을 실행하는 방법을 공유하겠습니다. 과거에는 cron 작업에서 웹 액세스 가능 URL인 wget을 사용하여 백그라운드 작업을 실행했습니다. 이로 인해 보안 문제가 발생하고 일부 성능 문제가 발생합니다. Security for Startup 시리즈에서 위험을 완화하는 몇 가지 방법을 논의하는 동안 콘솔 기반 명령으로 전환하고 싶었습니다.

현대 소프트웨어 개발에서 강력한 콘텐츠 관리 시스템(CMS)을 구축하는 것은 쉬운 일이 아닙니다. 개발자는 광범위한 기술과 경험을 보유해야 할 뿐만 아니라 기능과 성능을 최적화하기 위해 가장 진보된 기술과 도구를 사용해야 합니다. 이 기사에서는 널리 사용되는 오픈 소스 소프트웨어인 Yii2와 GrapeJS를 사용하여 백엔드 CMS와 프런트엔드 시각적 편집을 구현하는 방법을 소개합니다. Yii2는 빠르게 구축할 수 있는 풍부한 도구와 구성 요소를 제공하는 인기 있는 PHPWeb 프레임워크입니다.
