【面试那些事儿二】 PHP 常见问题

PHP 的垃圾回收机制:

PHP垃圾回收机制是php5之后才有的这<span id="transmark"></span>个东西,下面我来给大家介绍一下关于PHP垃圾回收机制一些理解,希望对各位同学有所帮助。  
  
php 5.3之前使用的垃圾回收机制是单纯的“引用计数”,也就是每个内存对象都分配一个计数器,当内存对象被变量引用时,计数器 1;当变量引用撤掉后,计数器-1;当计数器=0时,表明内存对象没有被使用,该内存对象则进行销毁,垃圾回收完成。  
  
“引用计数”存在问题,就是当两个或多个对象互相引用形成环状后,内存对象的计数器则不会消减为0;这时候,这一组内存对象已经没用了,但是不能回收,从而导致内存泄露;  
  
php5.3开始,使用了新的垃圾回收机制,在引用计数基础上,实现了一种复杂的算法,来检测内存对象中引用环的存在,以避免内存泄露  

将外网图片本地化、将外网图片下载到本地的原理

//将外网图片本地化、将外网图片下载到本地的原理  
copy("http://image.v1.cn/vodone/20150723/303862_0x0.jpg",'e:/wamp/www/303862_0x0.jpg');  

PHP缓存技术总结

/** 
 
1、全页面静态化缓存 
也就是将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程。此种方式,在CMS系 
统中比较常见,比如dedecms; 
一种比较常用的实现方式是用输出缓存: 
Ob_start() 
******要运行的代码******* 
$content = Ob_get_contents(); 
****将缓存内容写入html文件***** 
Ob_end_clean(); 
 
 
2、页面部分缓存 
该种方式,是将一个页面中不经常变的部分进行静态缓存,而经常变化的块不缓存,最后组装在一起显示;可以使用类似于 
ob_get_contents的方式实现,也可以利用类似ESI之类的页面片段缓存策略,使其用来做动态页面中相对静态的片段部分的缓存 
(ESI技术,请baidu,此处不详讲)。该种方式可以用于如商城中的商品页; 
 
 
3、数据缓存 
顾名思义,就是缓存数据的一种方式;比如,商城中的某个商品信息,当用商品id去请求时,就会得出包括店铺信息、商品信息 
等数据,此时就可以将这些数据缓存到一个php文件中,文件名包含商品id来建一个唯一标示;下一次有人想查看这个商品时,首 
先就直接调这个文件里面的信息,而不用再去数据库查询;其实缓存文件中缓存的就是一个php数组之类; 
Ecmall商城系统里面就用了这种方式; 
 
 
4、查询缓存 
其实这跟数据缓存是一个思路,就是根据查询语句来缓存;将查询得到的数据缓存在一个文件中,下次遇到相同的查询时,就直 
接先从这个文件里面调数据,不会再去查数据库;但此处的缓存文件名可能就需要以查询语句为基点来建立唯一标示(用md5($sql)???); 
按时间变更进行缓存 
其实,这一条不是真正的缓存方式;上面的2、3、4的缓存技术一般都用到了时间变更判断;就是对于缓存文件您需要设一个有效 
时间,在这个有效时间内,相同的访问才会先取缓存文件的内容,但是超过设定的缓存时间,就需要重新从数据库中获取数据, 
并生产最新的缓存文件; 
比如,我将我们商城的首页就是设置2个小时更新一次; 
 
 
5、按内容变更进行缓存 
这个也并非独立的缓存技术,需结合着用;就是当数据库内容被修改时,即刻更新缓存文件; 
比如,一个人流量很大的商城,商品很多,商品表必然比较大,这表的压力也比较重;我们就可以对商品显示页进行页面缓存; 
当商家在后台修改这个商品的信息时,点击保存,我们同时就更新缓存文件;那么,买家访问这个商品信息时,实际上访问的是 
一个静态页面,而不需要再去访问数据库; 
是想,如果对商品页不缓存,那么每次访问一个商品就要去数据库查一次,如果有10万人在线浏览商品,那服务器压力就大了; 
 
 
6、内存式缓存 
提到这个,可能大家想到的首先就是Memcached;memcached是高性能的分布式内存缓存服务器。 一般的使用目的是,通过缓存数 
据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、 提高可扩展性。 
它就是将需要缓存的信息,缓存到系统内存中,需要获取信息时,直接到内存中取;比较常用的方式就是 key-->value方式; 
     $memcachehost = '192.168.6.191'; 
     $memcacheport = 11211; 
     $memcachelife = 60; 
     $memcache = new Memcache; 
     $memcache->connect($memcachehost,$memcacheport) or die ("Could not connect"); 
     $memcache->set('key','缓存的内容'); 
     $get = $memcache->get($key);       //获取信息 
 
 
7、apache缓存模块 
apache安装完以后,是不允许被cache的。如果外接了cache或squid服务器要求进行web加速的话,就需要在htttpd.conf里进行设 
置,当然前提是在安装apache的时候要激活mod_cache的模块。 
安装apache时:./configure --enable-cache --enable-disk-cache --enable-mem-cache 
 
 
8、php APC缓存扩展 
Php有一个APC缓存扩展,windows下面为php_apc.dll,需要先加载这个模块,然后是在php.ini里面进行配置: 
[apc]  
     extension=php_apc.dll  
     apc.rfc1867 = on  
     upload_max_filesize = 100M  
     post_max_size = 100M  
     apc.max_file_size = 200M  
     upload_max_filesize = 1000M  
     post_max_size = 1000M  
     max_execution_time = 600 ;   每个PHP页面运行的最大时间值(秒),默认30秒  
     max_input_time = 600 ;       每个PHP页面接收数据所需的最大时间,默认60  
     memory_limit = 128M ;       每个PHP页面所吃掉的最大内存,默认8M 
 
 
9、Opcode缓存 
我们知道,php的执行流程可以用下图来展示: 
php的执行流程 
首先php代码被解析为Tokens,然后再编译为Opcode码,最后执行Opcode码,返回结果;所以,对于相同的php文件,第一次运行 
时可以缓存其Opcode码,下次再执行这个页面时,直接会去找到缓存下的opcode码,直接执行最后一步,而不再需要中间的步骤了。 
比较知名的是XCache、Turck MM Cache、PHP Accelerator等; 
 
**/

遍历函数:scandir()与glob()函数的区别

/** 
 *  scandir()与glob()函数的区别: 
 * 
 *  遍历文件夹、遍历目录、遍历子文件夹、遍历子目录、遍历文件 
 *  扫描单层文件夹的情况 
        1、scandir('E:/wamp/www/phpcms/'); 
 
            案例: 
 
            Array( 
                [0] => . 
                [1] => .. 
                [2] => admin.php 
                [3] => api 
                [4] => api.php 
                [5] => caches 
                [6] => crossdomain.xml 
                [7] => favicon.ico 
                [8] => html 
                [9] => index.html 
                [10] => index.php 
                [11] => js.html 
                [12] => nbproject 
                [13] => phpcms 
                [14] => phpsso_server 
                [15] => plugin.php 
                [16] => robots.txt 
                [17] => statics 
                [18] => uploadfile 
            ) 
 
        2、glob('E:/wamp/www/phpcms/*'); 
 
            案例: 
 
            Array( 
                [0] => E:/wamp/www/phpcms/admin.php 
                [1] => E:/wamp/www/phpcms/api 
                [2] => E:/wamp/www/phpcms/api.php 
                [3] => E:/wamp/www/phpcms/caches 
                [4] => E:/wamp/www/phpcms/crossdomain.xml 
                [5] => E:/wamp/www/phpcms/favicon.ico 
                [6] => E:/wamp/www/phpcms/html 
                [7] => E:/wamp/www/phpcms/index.html 
                [8] => E:/wamp/www/phpcms/index.php 
                [9] => E:/wamp/www/phpcms/js.html 
                [10] => E:/wamp/www/phpcms/nbproject 
                [11] => E:/wamp/www/phpcms/phpcms 
                [12] => E:/wamp/www/phpcms/phpsso_server 
                [13] => E:/wamp/www/phpcms/plugin.php 
                [14] => E:/wamp/www/phpcms/robots.txt 
                [15] => E:/wamp/www/phpcms/statics 
                [16] => E:/wamp/www/phpcms/uploadfile 
            ) 
 */  
echo "<pre>";print_r(scandir('E:/wamp/www/phpcms/'));//跟glob相比多出来两个元素,分别是: "." 和 ".."  
echo "<pre>";print_r(glob('E:/wamp/www/phpcms/*'));//以数组的形式返回与指定模式相匹配的文件名或目录  

如何在数组头部和尾部及任意位置插入元素?

①插入元素  
array_unshift();//在数组头部插入一个或多个元素    
array_push();//在数组尾部插入一个或多个元素   
array_splice($arr,$start,0,$arr1);//在数组的第$start+1个位置插入新元素(指的是头部和中部任意位置,但不包括尾部),注意:参数3一定要是0  
②删除元素  
array_shift();//删除数组中首个元素,并返回删除后的值  
array_pop();//删除数组的最后一个元素(出栈),并返回删除后的值  

php如何方式SQL注入?我们在查询数据库时,出于安全考虑,需要过滤一些非法字符防止SQL恶意注入

//我们在查询数据库时,出于安全考虑,需要过滤一些非法字符防止SQL恶意注入  
function injCheck($sql_str) {    
    $check = preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/', $sql_str);   
    if ($check) {   
        echo '非法字符!!';   
        exit;   
    } else {   
        return $sql_str;   
    }   
}  
  
echo injCheck('1 or 1=1');//提示:"非法字符!!"  

php如何强制下载文件?

//有时我们不想让浏览器直接打开文件,如PDF文件,而是要直接下载文件,那么以下函数可以强制下载文件,函数中使用了application/octet-stream头类型  
function download($filename){   
    if ((isset($filename))&&(file_exists($filename))){   
       header("Content-length: ".filesize($filename));   
       header('Content-Type: application/octet-stream');   
       header('Content-Disposition: attachment; filename="' . $filename . '"');   
       readfile("$filename");   
    } else {   
       echo "Looks like file does not exist!";   
    }   
}   
  
download('/down/test_45f73e852.zip');
php如何获取客户端真实IP?
//我们经常要用数据库记录用户的IP,以下代码可以获取客户端真实的IP:  
//获取用户真实IP   
function getIp() {   
    if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))   
        $ip = getenv("HTTP_CLIENT_IP");   
    else   
        if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))   
            $ip = getenv("HTTP_X_FORWARDED_FOR");   
        else   
            if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))   
                $ip = getenv("REMOTE_ADDR");   
            else   
                if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))   
                    $ip = $_SERVER['REMOTE_ADDR'];   
                else   
                    $ip = "unknown";   
    return ($ip);   
}   
  
echo getIp();//结果:您的IP是:221.223.234.138  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值