PHP autoload实现自动加载类

 更新时间:2016年11月25日 17:08  点击:1823
autoload机制可以使得PHP程序有可能在使用类时才自动包含类文件,而不是一开始就将所有的类文件include进来,这种机制也称为lazy loading。

下面是使用autoload机制加载Person类的例子:

 代码如下 复制代码

/* autoload.php */   
<?php    
function __autoload($classname) {
  require_once ($classname . “class.php”);
}    
$person = new Person(”Altair”, 6);
var_dump ($person);
?>    

PHP的autoload机制的实现

要在PHP中实现自动加载类,那就要说到一个魔术方法了,__autoload();这是PHP5添加的自动加载类方法。只要定义了该函数,那么如果PHP运行到该类找不到时,就会根据__autoload的规则去寻找。

自己也规划一下,跟set_include_path和get_include_path来配合使用,使自动加载类更完善点,代码飙一下(模仿magento的):

 代码如下 复制代码

 

$paths[] = BP . DS . ‘app’ . DS . ‘local’;
$paths[] = BP . DS . ‘app’ . DS . ‘base’;
$paths[] = BP . DS . ‘lib’;

$appPath = implode(PS, $paths);
set_include_path($appPath . PS . get_include_path());

这样就可以为PHP添加默认的类加载环境,这里只是把路径添加到了PHP环境,如果还要继续添加规则,可以再定义__autoload函数,不过我这里是对象使用的,就换了一种方法:spl_autoload_register方法,下面是自己根据magento的规则,自己弄了一套,其实跟magento差不多。

 代码如下 复制代码

class Autoload {

/**
* 自身对象
*
*/
protected static $_instance = null;

public function __construct() {

}

/*
* 实例化自身
*
*/

public static function instance() {
if (null == self::$_instance) {
self::$_instance = new self();
}

return self::$_instance;
}

/**
*
* 注册自动加载函数
*/
public static function register() {
spl_autoload_register(array(self::instance(), ‘autoload’));
}

/*
*
* 自动加载类
*/

public function autoload($class) {
if (!is_string($class)) {
return;
}

$classFile = str_replace(‘ ‘, DS, ucwords(str_replace(‘_’, ‘ ‘, $class)));
$classFile .= ‘.php’;
return include $classFile;
}

}

在php中为你提供memory_get_usage函数,可以检查到你服务器当前所使用的内存情况,有了这个函数我们可以实时的检查服务器状态了,下面我来介绍memory_get_usage用法。

格式化memory_get_usage()输出

 代码如下 复制代码

<?php
function convert($size){
$unit=array('b','kb','mb','gb','tb','pb');
return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
echo convert(memory_get_usage(true));
?>

输出:256 kb

PHP memory_get_usage() 函数还可以有个参数,$real_usage,其值为布尔值。默认为 FALSE,表示得到的内存使用量不包括该函数(PHP 内存管理器)占用的内存;当设置为 TRUE 时,得到的内存为不包括该函数(PHP 内存管理器)占用的内存。

 代码如下 复制代码

if (!function_exists('memory_get_usage')) 

 {
     function memory_get_usage() 

     {

        $pid = getmypid();

       if (IS_WIN) 

       {

            exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output);

             return preg_replace('/[^0-9]/', '', $output[5]) * 1024;

         } 

         else

        {

           exec("ps -eo%mem,rss,pid | grep $pid", $output);

           $output = explode(" ", $output[0]);

           return $output[1] * 1024;

         }

    }

}

在php中checkbox复选框我们以一般是使用数组形式来做的,这样在php 中获取复选框值时我们会以数组形式存储的,所以只要遍历数组即可实现。
 代码如下 复制代码

<html>
<head>
<title>获取复选框的值</title>
</head>
<body>
<form action="result.php" method="POST">
<input type="checkbox" name="year[]" value="1">1 &nbsp;&nbsp;
<input type="checkbox" name="year[]" value="2">2 &nbsp;&nbsp;
<input type="checkbox" name="year[]" value="3">3 <br>

<input type="submit" value="提交" />
</form>
</body>
</html>

php代码

 代码如下 复制代码

<?php
foreach($_POST['year'] as $item){
echo $item."<br>";
}
?>

在php中将html标签转换成纯文本的方法有不少,像php自带了函数strip_tags它就可以把html直接转换在纯文本文格式了,下面我来具体来看看各种转换代码。

先来看strip_tags()函数用法

下面的例子删除<a>标记之外的所有标记:

 代码如下 复制代码

<!--?php <br ?--> $input = "This <a href="http://www.111cn.net/">example</a>
is <strong>yanshare</strong>!";
echo strip_tags($input, "<a>");
?&gt;
</a>

输入结果

This <a href="http://www.111cn.net/">example</a>
is yanshare!

这里就连接连接与连接中的内容都过滤掉了,我们如果想保留A中的内容可以参考下面代码

strip_tags有一个可选的参数allowable_tags指定在此过程中可以跳过的标记。下面的例子使用了strip_tags()删除字符串中的所以HTML标记:

 代码如下 复制代码


<!--?php <br ?--> $input = "Email <a href="example@example.com">example@example.com</a>";
echo strip_tags($input);
?&gt;
这回返回以下结果:

Email example@example.com


一个自定义的将html转换为无html标签的字符集,返回转换好的字符串

 代码如下 复制代码

function html2text($str){
   $str = preg_replace("/<style .*?</style>/is", "", $str);  $str = preg_replace("/<script .*?</script>/is", "", $str);
   $str = preg_replace("/<br s*/?/>/i", "n", $str);
   $str = preg_replace("/</?p>/i", "nn", $str);
   $str = preg_replace("/</?td>/i", "n", $str);
   $str = preg_replace("/</?div>/i", "n", $str);
   $str = preg_replace("/</?blockquote>/i", "n", $str);
   $str = preg_replace("/</?li>/i", "n", $str);
   $str = preg_replace("/&nbsp;/i", " ", $str);
   $str = preg_replace("/&nbsp/i", " ", $str);
   $str = preg_replace("/&amp;/i", "&", $str);
   $str = preg_replace("/&amp/i", "&", $str);
   $str = preg_replace("/&lt;/i", "<", $str);
   $str = preg_replace("/&lt/i", "<", $str);
   $str = preg_replace("/&ldquo;/i", '"', $str);
   $str = preg_replace("/&ldquo/i", '"', $str);
   $str = preg_replace("/&lsquo;/i", "'", $str);
   $str = preg_replace("/&lsquo/i", "'", $str);
   $str = preg_replace("/&rsquo;/i", "'", $str);
   $str = preg_replace("/&rsquo/i", "'", $str);
   $str = preg_replace("/&gt;/i", ">", $str);
   $str = preg_replace("/&gt/i", ">", $str);
   $str = preg_replace("/&rdquo;/i", '"', $str);
   $str = preg_replace("/&rdquo/i", '"', $str);
   $str = strip_tags($str);
   $str = html_entity_decode($str, ENT_QUOTES, "utf-8");
   $str = preg_replace("/&#.*?;/i", "", $str);

   return $str;
  }

在php中file_get_contents与curl()函数都可以用来抓取对方网站的数据并保存到本地服务器中,但是总得来讲file_get_contents()效率稍低些,常用失败的情况、curl()效率挺高的,支持多线程,不过需要开启下curl扩展,也就是说要使用curl函数就必须要打开curl扩展了,而file_get_contents函数系统是默认的哦。

下面是curl扩展开启的步骤:

1、将PHP文件夹下的三个文件php_curl.dll,libeay32.dll,ssleay32.dll复制到system32下;
2、将php.ini(c:WINDOWS目录下)中的;extension=php_curl.dll中的分号去掉;

3、重启apache或者IIS。

我们先来看看两个函数的简单实例

curl()函数

 代码如下 复制代码

$ch = curl_init("http://www.111cn.net/");
curl_exec($ch);
curl_close($ch);

//$ch = curl_init("要采集的网址");  curl_init()函数的作用初始化一个curl会话

//curl_exec($ch);执行$ch

//curl_close($ch); 关闭$ch

file_get_contents函数

例子

 代码如下 复制代码
<?php
echo file_get_contents("http://www.111cn.net");
?>

输出:

 代码如下 复制代码

This is a test file with test text.

总结

fopen / file_get_contents 每次请求都会重新做DNS查询,并不对DNS信息进行缓存。
但是CURL会自动对DNS信息进行缓存。对同一域名下的网页或者图片的请求只需要一次DNS查询。这大大减少了DNS查询的次数。
所以CURL的性能比fopen / file_get_contents 好很多。


file_get_contents与curl效率及稳定性问题

 代码如下 复制代码

$config['context'] = stream_context_create(array('http' => array('method' => "GET",'timeout' => 5))); 

 
'timeout' => 5//这个超时时间不稳定,经常不好使。这时候,看一下服务器的连接池,会发现一堆类似下面的错误,让你头疼万分:

 代码如下 复制代码
file_get_contents(http://***): failed to open stream… 

 

不得已,安装了curl库,写了一个函数替换:

 代码如下 复制代码

function curl_get_contents($url)  
{  
   $ch = curl_init();  
   curl_setopt($ch, CURLOPT_URL, $url);            //设置访问的url地址  
   //curl_setopt($ch,CURLOPT_HEADER,1);            //是否显示头部信息  
   curl_setopt($ch, CURLOPT_TIMEOUT, 5);           //设置超时  
   curl_setopt($ch, CURLOPT_USERAGENT, _USERAGENT_);   //用户访问代理 User-Agent  
   curl_setopt($ch, CURLOPT_REFERER,_REFERER_);        //设置 referer  
    curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);      //跟踪301  
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        //返回结果  
    $r = curl_exec($ch);  
    curl_close($ch);  
    return $r;  

如此,除了真正的网络问题外,没再出现任何问题。
这是别人做过的关于curl和file_get_contents的测试:
file_get_contents抓取google.com需用秒数:

 代码如下 复制代码

1.2.31319094  
2.2.30374217  
3.2.21512604  
4.3.30553889  
5.2.30124092 

curl使用的时间:

1.0.68719101  
2.0.64675593  
3.0.64326  
4.0.81983113  
5.0.63956594 


那么如何根据服务器情况来使用file_get_contents还是curl()呢,下面我们可以利用function_exists函数来判断php是否支持一个函数可以轻松写出下面函数

 代码如下 复制代码

< ?php
 function vita_get_url_content($url) {
 if(function_exists('file_get_contents')) {
 $file_contents = file_get_contents($url);
 } else {
 $ch = curl_init();
 $timeout = 5; 
 curl_setopt ($ch, CURLOPT_URL, $url);
 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); 
 curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
 $file_contents = curl_exec($ch);
 curl_close($ch);
 }
 return $file_contents;
 }
 ?>

[!--infotagslink--]

相关文章

  • Laravel实现autoload方法详解

    本文给大家讲解的是在laravel中是怎么实现autoload的?分析之后才发现,真的是很巧妙,下面就来给大家详细说明下...2017-05-21
  • 类的自动加载

    当你尝试使用一个未定义的类时,PHP会报告一个致命错误. 解决方法就是添加一个类,可以用include包含一个文件. 究竟你知道要用到哪个类. 但是,PHP提供了类的自动加载功...2016-11-25
  • PHP5新特性,__autoload

    因为创建PYTHON中国(www.okpython.com)和推广PYTHON,所以一直没时间去研究PHP5的特性,现在终于有时间了。 今天说下__autoload函数的功能: 说明:自动加载类文件...2016-11-25
  • php自动加载__autoload()函数用法

    autoload在php主版本中是自动加载文件的一个方法了我们可以定义许多的文件在目录然后通过autoload加载了,下面来看看autoload函数用法。 在PHP5之后,我们可以通过...2016-11-25
  • php spl_autoload_register与__autoload方法详解

    php教程 spl_autoload_register与__autoload方法详解 在谈到框架自动加载类的方面,我大概翻了一下,现在主流的框架系统都使用spl_autoload_register函数,而非__autoload函...2016-11-25
  • php中__autoload()方法详解

    PHP在魔术函数__autoload()方法出现以前,如果你要在一个程序文件中实例化100个对象,那么你必须用include或者require包含进来100个类文件,或者你把这100个类定义在同一个...2016-11-25
  • 将DLL放入到资源中,运行时自动加载的小例子

    这篇文章介绍了将DLL放入到资源中,运行时自动加载的小例子,有需要的朋友可以参考一下...2020-06-25
  • PHP多线程(pthreads)与自动加载BUG问题

    php多线程功能是php5.3才真正的支持了,下面我就尝试了pthreads功能的一个测试同时也发测试时发现了一些bug了,具体bug原因还无法解决看其它朋友有经验吗 近日用PHP...2016-11-25
  • 分析Composer实现自动加载原理

    一般在框架中都会用到composer工具, 用它来管理依赖。其中 composer有类的自动加载机制,可以加载composer下载的库中的所有的类文件。那么composer的自动加载机制是怎么实现的呢?...2021-05-30
  • php中SPL spl_autoload_register与__autoload方法使用

    在php中spl_autoload_register与__autoload方法是php5才有的,下面我来给大家介绍这两个魔术函数的使用方法,大家可进入了解了解。 spl_autoload_register()函数应该...2016-11-25
  • php中autoload的实现例子介绍

    autoload在php中其实是一个魔术方法了,我们可以指定类目录及规则可以自动加载类文件从而可以省去我们使用include来加载文件了,下面一直来看看关于autoload方法一些例子...2016-11-25
  • PHP中__autoload和Smarty冲突的简单解决方法

    这篇文章主要介绍了PHP中__autoload和Smarty冲突的简单解决方法,通过spl_autoload_register注册__autoload函数的方法来解决__autoload函数再在Smarty无效的问题,需要的朋友可以参考下...2016-04-15
  • 基于jquery实现页面滚动到底自动加载数据的功能

    这篇文章主要介绍了基于jquery实现页面滚动到底自动加载数据的功能,感兴趣的小伙伴们可以参考一下...2015-12-21
  • PHP autoload实现自动加载类

    autoload机制可以使得PHP程序有可能在使用类时才自动包含类文件,而不是一开始就将所有的类文件include进来,这种机制也称为lazy loading。 下面是使用autoload机制...2016-11-25
  • php _autoload自动加载类与机制分析

    本文章详细的以实例来介绍了关于php _autoload自动加载类的用法以及如何使用_autoload来减少程序上的include和require的调用哦。 在使用PHP的OO模式开发系统时,...2016-11-25
  • php 自动加载函数 __autoload()

    php 自动加载函数 __autoload() PHP在魔术函数__autoload()方法出现以前,如果你要在一个程序文件中实例化100个对象,那么你必须用include或者require包含进来100个类文件...2016-11-25
  • PHP魔术函数__autoload的用法与一些问题

    本文章来讲述php5的一个新的功能,我们来介绍PHP魔术函数__autoload的用法与一些问题,下面给大家总结了用法过程中出现的一些问题与注意事项。 __autoload()用法 ph...2016-11-25
  • php类的注册与自动加载__autoload

    __autoload() 是PHP执行环境中约定的一个函数而非某个类的方法,如果一个类在使用之前没有加载到当前文件,会自动调用 __autoload() 函数来加载该类,通常这些类的加载规则...2016-11-25
  • 第十二节--类的自动加载 -- Classes and Objects in PHP5 [12]

    第十二节--类的自动加载 当你尝试使用一个未定义的类时,PHP会报告一个致命错误. 解决方法就是添加一个类,可以用include包含一个文件. 毕竟你知道要用到哪个类. 但是,...2016-11-25
  • php自动加载类__autoload()的方法

    本文章来给大家简单的介绍一下关于php自动加载类__autoload()的方法,希望此方法对各位同学会有所帮助哦。 作用:当在程序中需要实例化一个类,刚好这这类又不是在本文...2016-11-25