GVKun编程网logo

php – Alias类方法作为全局函数(php提供三种全局变量的定义方法,分别是?)

7

关于php–Alias类方法作为全局函数和php提供三种全局变量的定义方法,分别是?的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于c–在全局函数或全局函数包装的类中实现、ci-框架中全局

关于php – Alias类方法作为全局函数php提供三种全局变量的定义方法,分别是?的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于c – 在全局函数或全局函数包装的类中实现、ci - 框架中全局函数和PHP内置函数调用的先后问题?、CI框架源码阅读笔记3 全局函数Common.php、DedeCms全局函数 common.func.php 公用函数等相关知识的信息别忘了在本站进行查找喔。

本文目录一览:

php – Alias类方法作为全局函数(php提供三种全局变量的定义方法,分别是?)

php – Alias类方法作为全局函数(php提供三种全局变量的定义方法,分别是?)

是否可以将类方法别名为全局函数?

我有一个类作为PHP中gettext函数的包装器.我有一个名为_t()的函数来处理翻译.

我希望能够从我的代码中的任何地方将其称为_t(),而不必通过实例化对象($translate :: _ t())来实现,因为这看起来非常笨拙.

我想过使用命名空间给对象一个别名:

Use translations\TranslationClass as T

虽然这是一个更好的改进:T :: _ t().它仍然没有必要只需要做_t().

有没有在整个应用程序中将T :: _ t()替换为_t()?

解决方法

您可以创建包装函数或使用create_function().

function _t() {
    call_user_func_array(array('TranslationClass','_t'),func_get_arts());
}

或者你可以动态创建一个函数:

$t = create_function('$string','return TranslationClass::_t($string);');

// Which would be used as:
print $t('Hello,World');

c – 在全局函数或全局函数包装的类中实现

c – 在全局函数或全局函数包装的类中实现

我必须根据预定义的签名实现一组60个函数.它们必须是全局函数,而不是某些类的成员函数.当我实现它们时,我使用了第三方提供的一组很好的类.

我对大多数函数的实现很短,大约5到10行,并且主要处理对第3方类的不同访问.对于一些更复杂的函数,我创建了几个处理所有复杂内容的新类,我也在函数中使用它们.所有状态信息都存储在我和第三方类的静态成员中,因此我不必创建全局变量.

问题:如果我实现一个具有60个成员函数的大类,并且完成所有实现(现在在全局函数中)会更好吗?我必须编写的每个函数都只调用类中相应的成员函数.

解决方法

All the state information is stored in the static members of my and 3rd party’s classes,so I don’t have to create global variables.

这是关键点.不,他们绝对不应该上课.类被用于创建对象.在您的情况下,您可以将它们用作数据和功能的范围.但这就是名称空间已经更好地解决的问题:

namespace stuff {
    ... 60 functions ...
    namespace baz {
        ... if you want,you can have nested namespaces,to ...
        ... categorize the functions ...
    }

    namespace data {
        ... you can put data into an extra namespace if you want ...
    }
}

创建纯粹仅由静态成员组成的类是一个坏主意.

ci - 框架中全局函数和PHP内置函数调用的先后问题?

ci - 框架中全局函数和PHP内置函数调用的先后问题?

如题:求解惑;

回复内容:

如题:求解惑;

php是单线程,串行的

CI框架源码阅读笔记3 全局函数Common.php

CI框架源码阅读笔记3 全局函数Common.php

从本篇开始,将深入CI 框架 的内部,一步步去探索这个 框架 的实现、结构和设计。 Common.php文件定义了一系列的 全局 函数 (一般来说, 全局 函数 具有最高的加载优先权,因此大多数的 框架 中BootStrap引导文件都会最先引入 全局 函数 ,以便于之后的处理

  从本篇开始,将深入ci框架的内部,一步步去探索这个框架的实现、结构和设计。

  Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap引导文件都会最先引入全局函数,以便于之后的处理工作)。

  打开Common.php中,第一行代码就非常诡异:

1

<span>if</span> ( ! <span>defined</span>(''BASEPATH'')) <span>exit</span>(''No direct script access allowed'');

登录后复制

CI框架源码阅读笔记2 一切的入口 index.php)中,我们已经知道,BASEPATH是在入口文件中定义的常量。这里做这个判断的原因是:避免直接访问文件,而必须由index.php入口文件进入。其实不仅是Common.php,System中所有文件,几乎都要引入这个常量的判断,避免直接的脚本访问:

CI框架源码阅读笔记3 全局函数Common.php

立即学习“PHP免费学习笔记(深入)”;

本文件中定义的函数如下(查看方式 print_r(get_defined_functions())):

 CI框架源码阅读笔记3 全局函数Common.php

CI中所有全局函数的定义方式都为:

1

2

3

4

5

<span>if</span> ( ! <span>function_exists</span>(''func_name''<span>)){

    </span><span>function</span><span> func_name(){

     //function body

    }

}</span>

登录后复制

这样做,是为了防止定义重名函数(之后如果我们要定义系统的全局函数,也都将使用这种定义方式)。下面,一个个展开来看:

1.  is_php

这个函数的命名很明显,就是判断当前环境的PHP版本是否是特定的PHP版本(或者高于该版本)

函数内部有一个static的$_is_php数组变量,用于缓存结果(因为在特定的运行环境中,PHP的版本是已知的且是不变的,所以通过缓存的方式,避免每次调用时都去进行version_compare。这种方式,与一般的分布式缓存(如Redis)的处理思维是一致的,不同的是,这里是使用static数组的方式,而分布式缓存大多使用内存缓存)。

为什么要定义这个函数呢?这是因为,CI框架中有一些配置依赖于PHP的版本和行为(如magic_quotes,PHP 5.3版本之前,该特性用于指定是否开启转义,而PHP5.3之后,该特性已经被废弃)。这就好比是针对不同的浏览器进行Css Hack一样(这里仅仅是比喻,实际上,PHP并没有太多的兼容性问题)。

具体的实现源码:

1

2

3

4

5

6

7

8

9

10

11

<span>function</span> is_php(<span>$version</span> = ''5.0.0''<span>)

{

    </span><span>static</span> <span>$_is_php</span><span>;

    </span><span>$version</span> = (<span>string</span>)<span>$version</span><span>;

 

    </span><span>if</span> ( ! <span>isset</span>(<span>$_is_php</span>[<span>$version</span><span>]))

    {

        </span><span>$_is_php</span>[<span>$version</span>] = (<span>version_compare</span>(<span>PHP_VERSION</span>, <span>$version</span>) FALSE : <span>TRUE</span><span>;

    }

    </span><span>return</span> <span>$_is_php</span>[<span>$version</span><span>];

}</span>

登录后复制

2.  is_really_writable

这个函数用于判断文件或者目录是否真实可写,一般情况下,通过内置函数is_writable()返回的结果是比较可靠的,但是也有一些例外,比如:

(a).    Windows中,如果对文件或者目录设置了只读属性,则is_writable返回结果是true,但是却无法写入。

(b).    Linux系统中,如果开启了Safe Mode,则也会影响is_writable的结果

因此,本函数的处理是:

  如果是一般的Linux系统且没有开启safe mode,则直接调用is_writable

否则:

  如果是目录,则尝试在目录中创建一个文件来检查目录是否可写

  如果是文件,则尝试以写入模式打开文件,如果无法打开,则返回false

注意,即使是使用fopen检查文件是否可写,也一定记得调用fclose关闭句柄,这是一个好的习惯。

函数的源码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<span>function</span> is_really_writable(<span>$file</span><span>)

{

    </span><span>//</span><span> If we''re on a Unix server with safe_mode off we call is_writable</span>

    <span>if</span> (DIRECTORY_SEPARATOR == ''/'' AND @<span>ini_get</span>("safe_mode") == <span>FALSE</span><span>)

    {

        </span><span>return</span> <span>is_writable</span>(<span>$file</span><span>);

    }

 

    </span><span>//</span><span> For windows servers and safe_mode "on" installations we''ll actually write a file then read it</span>

    <span>if</span> (<span>is_dir</span>(<span>$file</span><span>))

    {

        </span><span>$file</span> = <span>rtrim</span>(<span>$file</span>, ''/'').''/''.<span>md5</span>(<span>mt_rand</span>(1,100).<span>mt_rand</span>(1,100<span>));

 

        </span><span>if</span> ((<span>$fp</span> = @<span>fopen</span>(<span>$file</span>, FOPEN_WRITE_CREATE)) === <span>FALSE</span><span>)

        {

            </span><span>return</span> <span>FALSE</span><span>;

        }

 

        </span><span>fclose</span>(<span>$fp</span><span>);

        @</span><span>chmod</span>(<span>$file</span>,<span> DIR_WRITE_MODE);

        @</span><span>unlink</span>(<span>$file</span><span>);

        </span><span>return</span> <span>TRUE</span><span>;

    }

    </span><span>elseif</span> ( ! <span>is_file</span>(<span>$file</span>) OR (<span>$fp</span> = @<span>fopen</span>(<span>$file</span>, FOPEN_WRITE_CREATE)) === <span>FALSE</span><span>)

    {

        </span><span>return</span> <span>FALSE</span><span>;

    }

 

    </span><span>fclose</span>(<span>$fp</span><span>);

    </span><span>return</span> <span>TRUE</span><span>;

}</span>

登录后复制

3.  load_class

这个函数有几个特殊的地方需要重点关注:

(1).    注意这个函数的签名,function &load_class( $class,$directory,$prefix).看到前面那个特殊的&符号没?没错,这个函数返回的是一个class实例的引用. 对该实例的任何改变,都会影响下一次函数调用的结果。

(2).    这个函数也有一个内部的static变量缓存已经加载的类的实例,实现方式类似于单例模式(Singleton)

(3).    函数优先查找APPPATH和BASEPATH中查找类,然后才从$directory中查找类,这意味着,如果directory中存在着同名的类(指除去前缀之后同名),CI加载的实际上是该扩展类。这也意味着,可以对CI的核心进行修改或者扩展。

下面是该函数的源码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

<span>function</span> &amp;load_class(<span>$class</span>, <span>$directory</span> = ''libraries'', <span>$prefix</span> = ''CI_''<span>)

{

    </span><span>/*</span><span> 缓存加载类的实例 </span><span>*/</span>

    <span>static</span> <span>$_classes</span> = <span>array</span><span>();

    </span><span>if</span> (<span>isset</span>(<span>$_classes</span>[<span>$class</span><span>]))

    {

        </span><span>return</span> <span>$_classes</span>[<span>$class</span><span>];

    }

    </span><span>$name</span> = <span>FALSE</span><span>;

 

    </span><span>/*</span><span> 先查找系统目录 </span><span>*/</span>

    <span>foreach</span> (<span>array</span>(APPPATH, BASEPATH) <span>as</span> <span>$path</span><span>)

    {

        </span><span>if</span> (<span>file_exists</span>(<span>$path</span>.<span>$directory</span>.''/''.<span>$class</span>.''.php''<span>))

        {

            </span><span>$name</span> = <span>$prefix</span>.<span>$class</span><span>;

            </span><span>if</span> (<span>class_exists</span>(<span>$name</span>) === <span>FALSE</span><span>)

            {

                </span><span>require</span>(<span>$path</span>.<span>$directory</span>.''/''.<span>$class</span>.''.php''<span>);

            }

            </span><span>break</span><span>;

        }

 

    }

 

    </span><span>/*</span><span>  查找之后并没有立即实例化,而是接着查找扩展目录 </span><span>*/</span>

    <span>if</span> (<span>file_exists</span>(APPPATH.<span>$directory</span>.''/''.config_item(''subclass_prefix'').<span>$class</span>.''.php''<span>))

    {

        </span><span>$name</span> = config_item(''subclass_prefix'').<span>$class</span><span>;

        </span><span>if</span> (<span>class_exists</span>(<span>$name</span>) === <span>FALSE</span><span>)

        {

            </span><span>require</span>(APPPATH.<span>$directory</span>.''/''.config_item(''subclass_prefix'').<span>$class</span>.''.php''<span>);

 

        }

    }

 

    </span><span>/*</span><span> 没有找到任何文件 </span><span>*/</span>

    <span>if</span> (<span>$name</span> === <span>FALSE</span><span>)

    {

        </span><span>exit</span>(''Unable to locate the specified class: ''.<span>$class</span>.''.php''<span>);

    }

 

    </span><span>/*</span><span>  将$class计入已加载的类列表  </span><span>*/</span><span>

    is_loaded(</span><span>$class</span><span>);

 

    </span><span>/*</span><span> 取得实例化 </span><span>*/</span>

    <span>$_classes</span>[<span>$class</span>] = <span>new</span> <span>$name</span><span>();

 

    </span><span>return</span> <span>$_classes</span>[<span>$class</span><span>];

}</span>

登录后复制

4.  is_loaded

这个函数用于追踪所有已加载的class。代码比较简洁,没有太多可讲的地方,这里直接贴出源码:

1

2

3

4

5

6

7

8

9

10

<span>function</span> &amp;is_loaded(<span>$class</span> = ''''<span>)

{

    </span><span>static</span> <span>$_is_loaded</span> = <span>array</span><span>();

 

    </span><span>if</span> (<span>$class</span> != ''''<span>)

    {

       </span><span>$_is_loaded</span>[<span>strtolower</span>(<span>$class</span>)] = <span>$class</span><span>;

    }

    </span><span>return</span> <span>$_is_loaded</span><span>;

}</span>

登录后复制

5.  get_config

这个函数用于加载主配置文件(即位于config/目录下的config.php文件,如果定义了针对特定ENVIRONMENT的config.php文件,则是该文件)。该函数的签名为:

function &get_config($replace = array())

有几个需要注意的点:

(1).   函数只加载主配置文件,而不会加载其他配置文件(这意味着,如果你添加了其他的配置文件,在框架预备完毕之前,不会读取你的配置文件)。在Config组件实例化之前,所有读取主配置文件的工作都由该函数完成。

(2).   该函数支持动态运行的过程中修改Config.php中的条目(配置信息只可能修改一次,因为该函数也有static变量做缓存,若缓存存在,则直接返回配置)

(3). Return $_config[0] = & $config。是config文件中$config的引用,防止改变Config的配置之后,由于该函数的缓存原因,无法读取最新的配置。

这里还有一点无法理解,作者使用了$_config数组来缓存config,而只使用了$_config[0],那么问题来了,为什么不用单一变量代替,即:$_config = & $config; 如果有知道原因的童鞋,麻烦告知一声。

函数的实现源码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

<span>function</span> &amp;get_config(<span>$replace</span> = <span>array</span><span>())

{

    </span><span>static</span> <span>$_config</span><span>;

 

    </span><span>if</span> (<span>isset</span>(<span>$_config</span><span>))

    {

        </span><span>return</span> <span>$_config</span>[0<span>];

    }

 

    </span><span>if</span> ( ! <span>defined</span>(''ENVIRONMENT'') OR ! <span>file_exists</span>(<span>$file_path</span> = APPPATH.''config/''.ENVIRONMENT.''/config.php''<span>))

    {

        </span><span>$file_path</span> = APPPATH.''config/config.php''<span>;

    }

 

    </span><span>if</span> ( ! <span>file_exists</span>(<span>$file_path</span><span>))

    {

        </span><span>exit</span>(''The configuration file does not exist.''<span>);

    }

 

    </span><span>require</span>(<span>$file_path</span><span>);

 

    </span><span>if</span> ( ! <span>isset</span>(<span>$config</span>) OR ! <span>is_array</span>(<span>$config</span><span>))

    {

        </span><span>exit</span>(''Your config file does not appear to be formatted correctly.''<span>);

    }

 

    </span><span>if</span> (<span>count</span>(<span>$replace</span>) &gt; 0<span>)

    {

        </span><span>foreach</span> (<span>$replace</span> <span>as</span> <span>$key</span> =&gt; <span>$val</span><span>)

        {

            </span><span>if</span> (<span>isset</span>(<span>$config</span>[<span>$key</span><span>]))

            {

                </span><span>$config</span>[<span>$key</span>] = <span>$val</span><span>;

            }

        }

    }

 

    </span><span>return</span> <span>$_config</span>[0] =&amp; <span>$config</span><span>;

}</span>

登录后复制

6.  config_item

这个函数调用了load_config,并获取相应的设置条目。代码比较简洁。不做过多的解释,同样只贴出源码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<span>function</span> config_item(<span>$item</span><span>)

{

    </span><span>static</span> <span>$_config_item</span> = <span>array</span><span>();

 

    </span><span>if</span> ( ! <span>isset</span>(<span>$_config_item</span>[<span>$item</span><span>]))

    {

        </span><span>$config</span> =&amp;<span> get_config();

 

        </span><span>if</span> ( ! <span>isset</span>(<span>$config</span>[<span>$item</span><span>]))

        {

            </span><span>return</span> <span>FALSE</span><span>;

        }

        </span><span>$_config_item</span>[<span>$item</span>] = <span>$config</span>[<span>$item</span><span>];

    }

 

    </span><span>return</span> <span>$_config_item</span>[<span>$item</span><span>];

}</span>

登录后复制

7.  show_error

 这是CI定义的可以用来展示错误信息的函数,该函数使用了Exceptions组件(之后我们将看到,CI中都是通过Exceptions组件来管理错误的)来处理错误。

 例如,我们可以在自己的应用程序控制器中调用该函数展示错误信息:

1

<span>Show_error(“trigger error info”);</span>

登录后复制

CI框架的错误输出还算是比较美观:

CI框架源码阅读笔记3 全局函数Common.php

注意该函数不仅仅是显示错误,而且会终止代码的执行(exit)

函数的源码:

1

2

3

4

5

6

<span>function</span> show_error(<span>$message</span>, <span>$status_code</span> = 500, <span>$heading</span> = ''An Error Was Encountered''<span>)

{

    </span><span>$_error</span> =&amp; load_class(''Exceptions'', ''core''<span>);

    </span><span>echo</span> <span>$_error</span>-&gt;show_error(<span>$heading</span>, <span>$message</span>, ''error_general'', <span>$status_code</span><span>);

    </span><span>exit</span><span>;

}</span>

登录后复制

8.  show_404

没有太多解释的东西,返回404页面

源码:

1

2

3

4

5

6

<span>function</span> show_404(<span>$page</span> = '''', <span>$log_error</span> = <span>TRUE</span><span>)

{

    </span><span>$_error</span> =&amp; load_class(''Exceptions'', ''core''<span>);

    </span><span>$_error</span>-&gt;show_404(<span>$page</span>, <span>$log_error</span><span>);

    </span><span>exit</span><span>;

}</span>

登录后复制

9.  log_message

调用Log组件记录log信息,类似Debug。需要注意的是,如果主配置文件中log_threshold被设置为0,则不会记录任何Log信息,该函数的源码:

1

2

3

4

5

6

7

8

9

10

11

12

<span>function</span> log_message(<span>$level</span> = ''error'', <span>$message</span>, <span>$php_error</span> = <span>FALSE</span><span>)

{

    </span><span>static</span> <span>$_log</span><span>;

 

    </span><span>if</span> (config_item(''log_threshold'') == 0<span>)

    {

        </span><span>return</span><span>;

    }

 

    </span><span>$_log</span> =&amp; load_class(''Log''<span>);

    </span><span>$_log</span>-&gt;write_log(<span>$level</span>, <span>$message</span>, <span>$php_error</span><span>);

}</span>

登录后复制

10.  set_status_header

CI框架允许你设置HTTP协议的头信息(具体的HTTP状态码和对应含义可以参考:http://blog.csdn.net/ohmygirl/article/details/6922313)。设置方法为:

$this->output->set_status_header(“401”,“lalalala”);(CI的Output组件暴露了set_status_header()对外接口,该接口即是调用set_status_header函数)

值得注意的是,现在很多服务器内部扩展加入了自定义的状态码,如nginx:

1

2

3

4

5

ngx_string(ngx_http_error_495_page),   /* 495,<span> https certificate error */

ngx_string(ngx_http_error_496_page)</span>,   /* 496,<span> https no certificate */

ngx_string(ngx_http_error_497_page)</span>,   /* 497,<span> http to https */

ngx_string(ngx_http_error_404_page)</span>,   /* 498,<span> canceled */

ngx_null_string</span>,                       /* 499, client has closed connection */

登录后复制

所以你在查看服务器的error_log时,如果看到了比较诡异的错误状态码,不要惊慌,这不是bug. 这也说明,如果你要自定义自己的状态码和状态码描述文案,可以在该函数的内部$stati变量中添加自定义的状态码和文案。更多详细的内容,可以查看header函数的manual。

源码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

<span>function</span> set_status_header(<span>$code</span> = 200, <span>$text</span> = ''''<span>)

{

    </span><span>/*</span><span> 所有的已定义状态码和描述文本 </span><span>*/</span>

    <span>$stati</span> = <span>array</span><span>(<br>     /* 2xx 成功 */

        </span>200    =&gt; ''OK'',

        201    =&gt; ''Created'',

        202    =&gt; ''Accepted'',

        203    =&gt; ''Non-Authoritative Information'',

        204    =&gt; ''No Content'',

        205    =&gt; ''Reset Content'',

        206    =&gt; ''Partial Content'',

        /* 3xx 重定向 */    

        300    =&gt; ''Multiple Choices'',

        301    =&gt; ''Moved Permanently'',

        302    =&gt; ''Found'',

        304    =&gt; ''Not Modified'',

        305    =&gt; ''Use Proxy'',

        307    =&gt; ''Temporary Redirect'',

        /* 4xx 客户端错误 */

        400    =&gt; ''Bad Request'',

        401    =&gt; ''Unauthorized'',

        403    =&gt; ''Forbidden'',

        404    =&gt; ''Not Found'',

        405    =&gt; ''Method Not Allowed'',

        406    =&gt; ''Not Acceptable'',

        407    =&gt; ''Proxy Authentication Required'',

        408    =&gt; ''Request Timeout'',

        409    =&gt; ''Conflict'',

        410    =&gt; ''Gone'',

        411    =&gt; ''Length Required'',

        412    =&gt; ''Precondition Failed'',

        413    =&gt; ''Request Entity Too Large'',

        414    =&gt; ''Request-URI Too Long'',

        415    =&gt; ''Unsupported Media Type'',

        416    =&gt; ''Requested Range Not Satisfiable'',

        417    =&gt; ''Expectation Failed'',

        /* 5xx 服务器端错误 */

        500    =&gt; ''Internal Server Error'',

        501    =&gt; ''Not Implemented'',

        502    =&gt; ''Bad Gateway'',

        503    =&gt; ''Service Unavailable'',

        504    =&gt; ''Gateway Timeout'',

        505    =&gt; ''HTTP Version Not Supported''<span>

    );

     

    </span><span>/*</span><span> 状态码为空或者不是数字,直接抛出错误并退出 </span><span>*/</span>

    <span>if</span> (<span>$code</span> == '''' OR ! <span>is_numeric</span>(<span>$code</span><span>))

    {

        show_error(</span>''Status codes must be numeric'', 500<span>);

    }

     

    </span><span>if</span> (<span>isset</span>(<span>$stati</span>[<span>$code</span>]) AND <span>$text</span> == ''''<span>)

    {

        </span><span>$text</span> = <span>$stati</span>[<span>$code</span><span>];

    }

     

    </span><span>/*</span><span> 设置的状态码不在已定义的数组中 </span><span>*/</span>

    <span>if</span> (<span>$text</span> == ''''<span>)

    {

        show_error(</span>''No status text available.  Please check your status code number or supply your own message text.'', 500<span>);

    }

 

    </span><span>$server_protocol</span> = (<span>isset</span>(<span>$_SERVER</span>[''SERVER_PROTOCOL''])) ? <span>$_SERVER</span>[''SERVER_PROTOCOL''] : <span>FALSE</span><span>;

     

    </span><span>/*</span><span> PHP以CGI模式运行 </span><span>*/</span>

    <span>if</span> (<span>substr</span>(<span>php_sapi_name</span>(), 0, 3) == ''cgi''<span>)

    {

        </span><span>header</span>("Status: {<span>$code</span>} {<span>$text</span>}", <span>TRUE</span><span>);

    }

    </span><span>elseif</span> (<span>$server_protocol</span> == ''HTTP/1.1'' OR <span>$server_protocol</span> == ''HTTP/1.0'')<span>/*</span><span> 检查HTTP协议 </span><span>*/</span><span>

    {

        </span><span>header</span>(<span>$server_protocol</span>." {<span>$code</span>} {<span>$text</span>}", <span>TRUE</span>, <span>$code</span><span>);

    }

    </span><span>else</span><span>

    {

        </span><span>header</span>("HTTP/1.1 {<span>$code</span>} {<span>$text</span>}", <span>TRUE</span>, <span>$code</span>);<span>/*</span><span>  默认为HTTP/1.1 </span><span>*/</span><span>

    }

}</span>

登录后复制

11.  _exception_handler

先看函数的签名:

function _exception_handler($severity, $message, $filepath, $line);

$ severity    :发生错误的错误码。整数

$message    :错误信息。

$filepath      :发生错误的文件

$line            :错误的行号

这个函数会根据当前设置的error_reporting的设置和配置文件中threshold的设置来决定PHP错误的显示和记录。在CI中,这个函数是作为set_error_handler的callback, 来代理和拦截PHP的错误信息(PHP手册中明确指出:以下级别的错误不能由用户定义的函数来处理E_ERRORE_PARSEE_CORE_ERRORE_CORE_WARNINGE_COMPILE_ERRORE_COMPILE_WARNING,和在 调用 set_error_handler() 函数所在文件中产生的大多数 E_STRICT 。同样,如果在set_error_handler调用之前发生的错误,也无法被_exception_handler捕获,因为在这之前,_exception_handler尚未注册)。

再看源码实现:

1

2

3

<span>if</span> (<span>$severity</span> == <span>E_STRICT</span><span>){

    </span><span>return</span><span>;

}</span>

登录后复制

E_STRICT是PHP5中定义的错误级别,是严格语法模式的错误级别,并不包含在E_STRICT. 由于E_STRICT级别的错误可能会很多,因此,CI的做法是,忽略这类错误。

函数中实际处理和记录错误信息的是Exception组件:

1

<span>$_error</span> =&amp; load_class(''Exceptions'', ''core'');

登录后复制

然后根据当前的error_reporting设置,决定是显示错误(show_php_error)还是记录错误日志(log_exception):

1

2

3

4

<span>if</span> ((<span>$severity</span> &amp; <span>error_reporting</span>()) == <span>$severity</span><span>)

{

    </span><span>$_error</span>-&gt;show_php_error(<span>$severity</span>, <span>$message</span>, <span>$filepath</span>, <span>$line</span><span>);

}</span>

登录后复制

注意,这里是位运算&而不是逻辑运算&&, 由于PHP中定义的错误常量都是整数,而且是2的整数幂(如

  1       E_ERROR

  2       E_WARNING

  4       E_PARSE

  8       E_NOTICE        

  16     E_CORE_ERROR

  ...

),因此可以用&方便判断指定的错误级别是否被设置,而在设置的时候,可以通过|运算:

1

2

3

4

5

<span>/*</span><span> 显示E_ERROR,E_WARNING,E_PARSE错误 </span><span>*/</span>

<span>error_reporting</span>(<span>E_ERROR</span> | <span>E_WARNING</span> | <span>E_PARSE</span><span>);

 

</span><span>/*</span><span> 显示除了E_NOTICE之外的错误 </span><span>*/</span>

<span>error_reporting</span>(<span>E_ALL</span> &amp; ~<span>E_NOTICE</span> | E_STRICE);

登录后复制

这与Linux的权限设置rwx的设计思想是一致的(r:4  w:2  x:1)

有时候仅仅显示错误是不够的,还需要记录错误信息到文件:

如果主配置文件config.php中$config[''log_threshold''] == 0,则不记录到文件:

1

2

3

4

<span>if</span> (config_item(''log_threshold'') == 0<span>)

{

    </span><span>return</span><span>;

}</span>

登录后复制

否者,记录错误信息到文件(这之中,调用组件Exception去写文件,Exception组件中会调用log_message函数,最终通过Log组件记录错误信息到文件。模块化的一个最大特点是每个组件都负责专门的职责,而模块可能还会暴露接口被其他组件调用。)

最后,贴上完整的源码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<span>function</span> _exception_handler(<span>$severity</span>, <span>$message</span>, <span>$filepath</span>, <span>$line</span><span>)

{

    </span><span>if</span> (<span>$severity</span> == <span>E_STRICT</span><span>)

    {

               </span><span>return</span><span>;

    }

    </span><span>$_error</span> =&amp; load_class(''Exceptions'', ''core''<span>);

 

    </span><span>if</span> ((<span>$severity</span> &amp; <span>error_reporting</span>()) == <span>$severity</span><span>)

    {

               </span><span>$_error</span>-&gt;show_php_error(<span>$severity</span>, <span>$message</span>, <span>$filepath</span>, <span>$line</span><span>);

    }

    </span><span>if</span> (config_item(''log_threshold'') == 0<span>)

    {

               </span><span>return</span><span>;

    }

    </span><span>$_error</span>-&gt;log_exception(<span>$severity</span>, <span>$message</span>, <span>$filepath</span>, <span>$line</span><span>);

}</span>

登录后复制

12.  Remove_invisiable_character

这个函数的含义非常明确,就是去除字符串中的不可见字符。这些不可见字符包括:

ASCII码表中的00-31,127(保留09,10,13,分别为tab,换行和回车换行,这些虽然不可见,但却是格式控制字符)。然后通过正则替换去除不可见字符:

1

2

3

4

<span>do</span><span>{

    </span><span>$str</span> = <span>preg_replace</span>(<span>$non_displayables</span>, '''', <span>$str</span>, -1, <span>$count</span><span>);

}

</span><span>while</span> (<span>$count</span>);

登录后复制

理论上将,preg_replace会替换所有的满足正则表达式的部分,这里使用while循环的理由是:可以去除嵌套的不可见字符。如  %%0b0c。如果只执行一次替换的话,剩余的部分%0c依然是不可见字符,所以要迭代去除($count返回替换的次数)。

完整的函数源码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<span>function</span> remove_invisible_characters(<span>$str</span>, <span>$url_encoded</span> = <span>TRUE</span><span>)

{

    </span><span>$non_displayables</span> = <span>array</span><span>();

 

    </span><span>if</span> (<span>$url_encoded</span><span>)

    {

        </span><span>$non_displayables</span>[] = ''/%0[0-8bcef]/'';    <span>//</span><span> url encoded 00-08, 11, 12, 14, 15</span>

        <span>$non_displayables</span>[] = ''/%1[0-9a-f]/'';       <span>//</span><span> url encoded 16-31</span>

<span>    }      

 

    </span><span>$non_displayables</span>[] = ''/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'';     <span>//</span><span> 00-08, 11, 12, 14-31, 127</span>

 

    <span>do</span><span>

    {

        </span><span>$str</span> = <span>preg_replace</span>(<span>$non_displayables</span>, '''', <span>$str</span>, -1, <span>$count</span><span>);

    }</span><span>while</span> (<span>$count</span><span>);

     

    </span><span>return</span> <span>$str</span><span>;

}</span>

登录后复制

13.  Html_escape

这个函数,实际上是数组中的元素递归调用htmlspecialchars。

函数实现源码:

1

2

3

4

5

6

7

8

9

10

11

<span>function</span> html_escape(<span>$var</span><span>)

{

    </span><span>if</span> (<span>is_array</span>(<span>$var</span><span>))

    {

        </span><span>return</span> <span>array_map</span>(''html_escape'', <span>$var</span><span>);

    }

    </span><span>else</span><span>

    {

        </span><span>return</span> <span>htmlspecialchars</span>(<span>$var</span>, ENT_QUOTES, config_item(''charset''<span>));

    }

}</span>

登录后复制

总结一下,Common.php是在各组件加载之前定义的一系列全局函数。这些全局函数的作用是获取配置、跟踪加载class、安全性过滤等。而这么做的目的之一,就是避免组件之间的过多依赖。

参考文献:

PHP引用:http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/09/10/2173092.html

HTTP协议:http://www.cnblogs.com/TankXiao/archive/2012/02/13/2342672.html

单例模式:http://cantellow.iteye.com/blog/838473

DedeCms全局函数 common.func.php 公用函数

DedeCms全局函数 common.func.php 公用函数

 

DedeCms V5.3 全局函数 common.func.php 公用函数

获得当前的脚本URL 
function GetCurUrl() 

返回格林威治标准时间 
function MyDate($format='Y-m-d H:i:s',$timest=0) 

把全角数字转为半角 
function GetAlabNum($fnum) 

把含HTML的内容转为纯text 
function Html2Text($str,$r=0) 

把文本转HTML 
function Text2Html($txt) 

输出Ajax头 
function AjaxHead() 

中文截取2,单字节截取模式 
function cn_substr($str,$slen,$startdd=0) 

把标准时间转为Unix时间戳 
function GetMkTime($dtime) 

获得一个 0000-00-00 00:00:00 标准格式的时间 
function GetDateTimeMk($mktime) 

获得一个 0000-00-00 标准格式的日期 
function GetDateMk($mktime) 

获得用户IP 
function GetIP() 

获取拼音以gbk编码为准 
function GetPinyin($str,$ishead=0,$isclose=1) 

dedecms通用消息提示框 
function ShowMsg($msg,$gourl,$onlymsg=0,$limittime=0) 

保存一个cookie 
function PutCookie($key,$value,$kptime=0,$pa="/") 

删除一个cookie 
function DropCookie($key) 

获取cookie 
function GetCookie($key) 

获取验证码 
function GetCkVdValue() 

过滤前台用户输入的文本内容 
// $rptype = 0 表示仅替换 html标记 
// $rptype = 1 表示替换 html标记同时去除连续空白字符 
// $rptype = 2 表示替换 html标记同时去除所有空白字符 
// $rptype = -1 表示仅替换 html危险的标记 
function HtmlReplace($str,$rptype=0) 

获得某文档的所有tag 
function GetTags($aid) 

过滤用于搜索的字符串 
function FilterSearch($keyword) 

处理禁用HTML但允许换行的内容 
function TrimMsg($msg) 

获取单篇文档信息 
function GetOneArchive($aid)

本文章网址:http://www.ppssdd.com/code/6338.html。转载请保留出处,谢谢合作!

今天关于php – Alias类方法作为全局函数php提供三种全局变量的定义方法,分别是?的分享就到这里,希望大家有所收获,若想了解更多关于c – 在全局函数或全局函数包装的类中实现、ci - 框架中全局函数和PHP内置函数调用的先后问题?、CI框架源码阅读笔记3 全局函数Common.php、DedeCms全局函数 common.func.php 公用函数等相关知识,可以在本站进行查询。

本文标签: