php输出控制的学习笔记

 更新时间:2016年11月25日 17:22  点击:2022
php输出控制只影响到echo输出不会影响到位cookie,session,header这些函数了,下面来看下本文章。

1、简介

当PHP脚本有输出时,输出控制函数可以用这些来控制输出。这在多种不同情况中非常有用,尤其是用来在脚本开始输出 数据后,发送http头信息到浏览器。输出控制函数不影响由 header()或setcookie()发送的文件头信息,仅影响像echo这样的函数和PHP代码块间的数据。

 2、作用

1)、如官方介绍说,为了避免在输出文件头信息如header()和setcookie()之前出现输出而发生的错误。可以使用输出缓存函数。如下代码

 代码如下 复制代码
<?php
    ob_start();      //打开缓存控制函数
    echo 'hello';
    header('Location: http://www.111cn.net/');
?>

2)、将输出内容放入缓存区,如需进行其他操作,如将输出写入缓存文件,可将缓冲区内容写入缓存文件,然后输出。

 代码如下 复制代码
 ob_start();
    echo 'hello';
    $file = ob_get_contents();
    ob_end_clean();
    write_cache($file);    //将缓冲区内容写入缓存函数,实现细节省略

3)、获取某些无返回值内置函数的输出内容,如phpinnfo();

 代码如下 复制代码
<?php
ob_start();
phpinfo();
$file = ob_get_contents();   //phpinfo()输出内容
ob_end_clean();
 
?>

4)、在使用框架的时候,我们会发现框架中会将输出缓冲然后进行变量替换。最后输出。

除了这些内容,我们还可以利用输出缓存进行错误处理,具体看代码。我们可以将错误信息获取,以更加友好的方式输出。

 代码如下 复制代码
<?php
 
function display_error()
{
 if($errors = error_get_last())
 {
  return var_export($errors , TRUE);
 }
 return FALSE;
}
 
$dis_error = 'display_error';
 
//$a = 3;
 
ob_start( $dis_error );
 
echo $a;

附:ob_start()官方解释:

bool ob_start ([ callback $output_callback [, int $chunk_size [, bool $erase ]]] )

此函数将打开输出缓冲。当输出缓冲激活后,脚本将不会输出内容(除http标头外),相反需要输出的内容被存储在内部缓冲区中。

内部缓冲区的内容可以用 ob_get_contents() 函数复制到一个字符串变量中。 想要输出存储在内部缓冲区中的内容,可以使用 ob_end_flush() 函数。另外, 使用 ob_end_clean() 函数会静默丢弃掉缓冲区的内容。

output_callback
可选参数 output_callback 函数可以被指定。 此函数把一个字符串当作参数并返回一个字符串。 当输出缓冲区被( ob_flush(), ob_clean() 或者相似的函数)冲刷(送出)或者被清洗的时候;或者在请求结束之际输出缓冲区内容被冲刷到浏览器的时候该函数将会被调用。 当调用 output_callback 时,它将收到输出缓冲区的内容作为参数 并预期返回一个新的输出缓冲区作为结果,这个新返回的输出缓冲区内容将被送到浏览器。 如果这个 output_callback 不是一个可以调用的函数,此函数 会返回 FALSE 。

如果回调函数有两个参数,第二个参数会由一个位域补充,该位域由 PHP_OUTPUT_HANDLER_START, PHP_OUTPUT_HANDLER_CONT 和 PHP_OUTPUT_HANDLER_END 组成。

如果 output_callback 返回 FALSE ,其原来的输入 内容被直接送到浏览器。

这个参数 output_callback 可以通过直接给一个 NULL 值而避开。

ob_end_clean(), ob_end_flush(), ob_clean(), ob_flush() and ob_start() 不能从一个回调函数中调用。 如果从回调函数中调用了它们,产生的行为是不明确的。 如果想要删除缓冲区的内容,从回调函数中返回一个”" (空字符串)。 更不能从一个回调函数中使用像print_r($expression, true) 或highlight_file($filename, true) 一样的输出缓冲函数。

冒泡排序和快速排序算法在开发应用中各有优点了,下面我们来看几个关于php排序的几个例子。

使用PHP描述冒泡排序和快速排序算法,对象可以是一个数组。
使用PHP描述顺序查找和二分查找(也叫做折半查找)算法,顺序查找必须考虑效率,对象可以是一个有序数组。
写一个二维数组排序算法函数,能够具有通用性,可以调用php内置函数

1. 使用PHP描述冒泡排序和快速排序算法,对象可以是一个数组

 代码如下 复制代码

function bubble_sort($array)
{
$count = count($array);
if ($count <= 0) return false;
for($i=0; $i<$count; $i++){
for($j=$count-1; $j>$i; $j–){
if ($array[$j] < $array[$j-1]){
$tmp = $array[$j];
$array[$j] = $array[$j-1];
$array[$j-1] = $tmp;
}
}
}
return $array;
}


function quick_sort($array) {
if (count($array) <= 1) return $array;
$key = $array[0];
$left_arr = $right_arr = array();
foreach ($array as $val){
if ($val < = $key)
$left_arr[] = $val;
else
$right_arr[] = $val;
}
$left_arr = quick_sort($left_arr);
$right_arr = quick_sort($right_arr);
return array_merge($left_arr, array($key), $right_arr);
}

2. 使用PHP描述顺序查找和二分查找(也叫做折半查找)算法,顺序查找必须考虑效率,对象可以是一个有序数组

 代码如下 复制代码
function bin_sch($array, $low, $high, $k){
if ($low <= $high){
$mid = intval(($low+$high)/2);
if ($array[$mid] == $k){
return $mid;
}elseif ($k < $array[$mid]){
return bin_sch($array, $low, $mid-1, $k);
}else{
return bin_sch($array, $mid+1, $high, $k);
}
}
return -1;
}function seq_sch($array, $n, $k){
$array[$n] = $k;
for($i=0; $i<$n; $i++){
if($array[$i]==$k){
break;
}
}
if ($i<$n){
return $i;
}else{
return -1;
}
}

3. 写一个二维数组排序算法函数,能够具有通用性,可以调用php内置函数

 代码如下 复制代码

function array_sort($arr, $keys, $order=0) {
if (!is_array($arr)) {
return false;
}
$keysvalue = array();
foreach($arr as $key => $val) {
$keysvalue[$key] = $val[$keys];
}
if($order == 0){
asort($keysvalue);
}else {
arsort($keysvalue);
}
reset($keysvalue);
foreach($keysvalue as $key => $vals) {
$keysort[$key] = $key;
}
$new_array = array();
foreach($keysort as $key => $val) {
$new_array[$key] = $arr[$val];
}
return $new_array;
}

下面给各位整理几个PHP读取大文件例子,本文章讲到的是测试文章在800M的数据哦,更大的文件小编没有测试过哦。

在PHP中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file、file_get_contents之类的函数,简简单单的几行代码就能很漂亮的完成我们所需要的功能。但当所操作的文件是一个比较大的文件时,这些函数可能就显的力不从心, 下面将从一个需求入手来说明对于读取大文件时,常用的操作方法。

需求

有一个800M的日志文件,大约有500多万行, 用PHP返回最后几行的内容。

实现方法

1. 直接采用file函数来操作

由于 file函数是一次性将所有内容读入内存,而PHP为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不足,使服务器出现宕机,所以默认情况下限制只能最大使用内存16M,这是通过php.ini里的 memory_limit = 16M 来进行设置,这个值如果设置-1,则内存使用量不受限制。

下面是一段用file来取出这具文件最后一行的代码:

 代码如下 复制代码
<?php
ini_set('memory_limit', '-1');
$file = 'access.log';
$data = file($file);
$line = $data[count($data) - 1];
echo $line;
?>

整个代码执行完成耗时 116.9613 (s)。

我机器是2个G的内存,当按下F5运行时,系统直接变灰,差不多20分钟后才恢复过来,可见将这么大的文件全部直接读入内存,后果是多少严重,所以不在万 不得以,memory_limit这东西不能调得太高,否则只有打电话给机房,让reset机器了。

2.直接调用Linux的 tail 命令来显示最 后几行

在Linux命令行下,可以直接使用 tail -n 10 access.log 很轻易的显示日志文件最后几行,可以直接用PHP来调用tail命令,执行PHP代码如下:

 代码如下 复制代码
<?php
$file = 'access.log';
$file = escapeshellarg($file); // 对命令行参数进行安全转义
$line = `tail -n 1 $file`;
echo $line;
?>

整个代码执行完成耗时 0.0034 (s)

3. 直接使用PHP的 fseek 来进行文件操作

这种方式是最为普遍的方式,它不需要将文件的内容全部读入内容,而是直接通过指针来操作,所以效率是相当高效的。在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的,下面是常用的两种方法:

方法一

首先通过fseek找到文件的最后一位EOF,然后找最后一行的起始位置,取这一行的数据,再找次一行的起始位置, 再取这一行的位置,依次类推,直到找到了$num行。

#实现代码如下

 代码如下 复制代码
<?php
$fp = fopen($file, "r");
$line = 10;
$pos = -2;
$t = " ";
$data = "";
while ($line > 0)
{
 while ($t != "\n")
 {
  fseek($fp, $pos, SEEK_END);
  $t = fgetc($fp);
  $pos--;
 }
 $t = " ";
 $data .= fgets($fp);
 $line--;
}
fclose($fp);
echo $data
?>

整个代码执行完成耗时 0.0095 (s)

方法二

还是采用fseek的方式从文件最后开始读,但这时不是一位一位的读,而是一块一块的读,每读一块数据时,就将读取后的数据放在一个buf里,然后通过换 行符(\n)的个数来判断是否已经读完最后$num行数据。

#实现代码如下

 代码如下 复制代码
<?php
$fp = fopen($file, "r");
$num = 10;
$chunk = 4096;
$fs = sprintf("%u", filesize($file));
$max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file);
for ($len = 0; $len < $max; $len += $chunk)
{
 $seekSize = ($max - $len > $chunk) ? $chunk : $max - $len;
 fseek($fp, ($len + $seekSize) * -1, SEEK_END);
 $readData = fread($fp, $seekSize) . $readData;
 if (substr_count($readData, "\n") >= $num + 1)
 {
  preg_match("!(.*?\n){" . ($num) . "}$!", $readData, $match);
  $data = $match[0];
  break;
 }
}
fclose($fp);
echo $data;
?>

整个代码执行完成耗时 0.0009(s)。

方法三

 代码如下 复制代码

<?php
function tail($fp, $n, $base = 5)
{
 assert($n > 0);
 $pos = $n + 1;
 $lines = array();
 while (count($lines) <= $n)
 {
  try
  {
   fseek($fp, -$pos, SEEK_END);
  }
  catch (Exception $e)
  {
   fseek(0);
   break;
  }
  $pos *= $base;
  while (!feof($fp))
  {
   array_unshift($lines, fgets($fp));
  }
 }

 return array_slice($lines, 0, $n);
}

var_dump(tail(fopen("access.log", "r+"), 10));
?>

整个代码执行完成耗时 0.0003(s)

php,curl函数组可以帮助我们把机器为装成人行为来抓取网站,下面来分享两个例子,一个是访问http网页,一个访问https网页,下面一起看看。

每次要使用curl的时候,总要查一堆资料。

现在将常用的几句保存下来,省的每次都去谷歌。

常规curl请求:

 

 代码如下 复制代码
$url = 'http://www.111cn.net';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($curl);
curl_close($curl);
var_dump($data);

使用curl请求HTTPS:

 

 代码如下 复制代码
$url = 'https://www.111cn.net';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);//这个是重点。
$data = curl_exec($curl);
curl_close($curl);
var_dump($data);

注意

当请求https的数据时,会要求证书,这时候,加上下面这两个参数,规避ssl的证书检查

 代码如下 复制代码
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
读取大文件一直是一个头痛的问题,我们像使用php开发读取小文件可以直接使用各种函数实现,但一到大文章就会发现常用的方法是无法正常使用或时间太长太卡了,下面我们就一起来看看关于php读取大文件问题解决办法,希望例子能帮助到各位。

在PHP中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file、file_get_contents之类的函数,简简单单的几行代码就能 很漂亮的完成我们所需要的功能。但当所操作的文件是一个比较大的文件时,这些函数可能就显的力不从心, 下面将从一个需求入手来说明对于读取大文件时,常用的操作方法。
需求需求
有一个800M的日志文件,大约有500多万行, 用PHP返回最后几行的内容。
实现方法
1. 直接采用file函数来操作
由于 file函数是一次性将所有内容读入内存,而PHP为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不足,使服务器出现宕机,所以默认情况下限制只能最大使用内存16M,这是通过php.ini里的 memory_limit = 16M 来进行设置,这个值如果设置-1,则内存使用量不受限制。
下面是一段用file来取出这具文件最后一行的代码:

 代码如下 复制代码
<?php
ini_set('memory_limit', '-1');
$file = 'access.log';
$data = file($file);
$line = $data[count($data) - 1];
echo $line;
?>

整个代码执行完成耗时 116.9613 (s)。
我机器是2个G的内存,当按下F5运行时,系统直接变灰,差不多20分钟后才恢复过来,可见将这么大的文件全部直接读入内存,后果是多少严重,所以不在万 不得以,memory_limit这东西不能调得太高,否则只有打电话给机房,让reset机器了。
2.直接调用Linux的 tail 命令来显示最 后几行
在Linux命令行下,可以直接使用 tail -n 10 access.log 很轻易的显示日志文件最后几行,可以直接用PHP来调用tail命令,执行PHP代码如下:

 代码如下 复制代码
<?php
$file = 'access.log';
$file = escapeshellarg($file); // 对命令行参数进行安全转义
$line = `tail -n 1 $file`;
echo $line;
?>

整个代码执行完成耗时 0.0034 (s)
3. 直接使用PHP的 fseek 来进行文件操作
这种方式是最为普遍的方式,它不需要将文件的内容全部读入内容,而是直接通过指针来操作,所以效率是相当高效的。在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的,下面是常用的两种方法:
方法一
首先通过fseek找到文件的最后一位EOF,然后找最后一行的起始位置,取这一行的数据,再找次一行的起始位置, 再取这一行的位置,依次类推,直到找到了$num行。
#实现代码如下

 代码如下 复制代码
<?php
$fp = fopen($file, "r");
$line = 10;
$pos = -2;
$t = " ";
$data = "";
while ($line > 0)
{
 while ($t != "\n")
 {
  fseek($fp, $pos, SEEK_END);
  $t = fgetc($fp);
  $pos--;
 }
 $t = " ";
 $data .= fgets($fp);
 $line--;
}
fclose($fp);
echo $data
?>

整个代码执行完成耗时 0.0095 (s)
方法二
还是采用fseek的方式从文件最后开始读,但这时不是一位一位的读,而是一块一块的读,每读一块数据时,就将读取后的数据放在一个buf里,然后通过换 行符(\n)的个数来判断是否已经读完最后$num行数据。
#实现代码如下

 代码如下 复制代码
<?php
$fp = fopen($file, "r");
$num = 10;
$chunk = 4096;
$fs = sprintf("%u", filesize($file));
$max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file);
for ($len = 0; $len < $max; $len += $chunk)
{
 $seekSize = ($max - $len > $chunk) ? $chunk : $max - $len;
 fseek($fp, ($len + $seekSize) * -1, SEEK_END);
 $readData = fread($fp, $seekSize) . $readData;
 if (substr_count($readData, "\n") >= $num + 1)
 {
  preg_match("!(.*?\n){" . ($num) . "}$!", $readData, $match);
  $data = $match[0];
  break;
 }
}
fclose($fp);
echo $data;
?>

整个代码执行完成耗时 0.0009(s)。

方法三

 代码如下 复制代码

<?php
function tail($fp, $n, $base = 5)
{
 assert($n > 0);
 $pos = $n + 1;
 $lines = array();
 while (count($lines) <= $n)
 {
  try
  {
   fseek($fp, -$pos, SEEK_END);
  }
  catch (Exception $e)
  {
   fseek(0);
   break;
  }
  $pos *= $base;
  while (!feof($fp))
  {
   array_unshift($lines, fgets($fp));
  }
 }

 return array_slice($lines, 0, $n);
}

var_dump(tail(fopen("access.log", "r+"), 10));
?>

整个代码执行完成耗时 0.0003(s)

方法四,PHP的stream_get_line函数 ,读取快速,读取50万条数据大文件,大概需要20秒左右的时间!例子代码如下

 代码如下 复制代码
$fp = fopen('./iis.log', 'r'); //文件
while (!feof($fp)) {
 //for($j=1;$j<=1000;$j++) {         //读取下面的1000行并存储到数组中
  $logarray[] = stream_get_line($fp, 65535, "\n");
        // break;
  // }
 
 }
[!--infotagslink--]

相关文章

  • PyTorch一小时掌握之迁移学习篇

    这篇文章主要介绍了PyTorch一小时掌握之迁移学习篇,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-08
  • php上传图片学习笔记与心得

    我们在php中上传文件就必须使用#_FILE变量了,这个自动全局变量 $_FILES 从 PHP 4.1.0 版本开始被支持。在这之前,从 4.0.0 版本开始,PHP 支持 $HTTP_POST_FILES 数组。这...2016-11-25
  • Smarty模板学习笔记之Smarty简介

    1、简介Smarty是一个使用PHP写出来的模板PHP模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离。简单的讲,目...2014-05-31
  • php Observer观察者模式之学习笔记

    当我们在星际中开地图和几家电脑作战的时候,电脑的几个玩家相当于结盟,一旦我们出兵进攻某一家电脑,其余的电脑会出兵救援。 那么如何让各家电脑知道自己的盟友被攻击了...2016-11-25
  • PHP 日期函数 学习笔记介绍

    举一个简单的date例子 我将使用echo命令把内容输出到我们的客户端(浏览器)。我将使用下面的代码做为基础代码。 代码如下 复制代码 <!DOCTY...2016-11-25
  • 学习 Vue.js 遇到的那些坑

    这篇文章主要介绍了学习 Vue.js 遇到的那些坑,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下...2021-02-04
  • 开启BootStrap学习之旅

    当下最流行的前端开发框架Bootstrap,可大大简化网站开发过程,从而深受广大开发者的喜欢,你如果也喜欢Bootstrap前端开发框架,不要错过这次旅行...2016-05-05
  • 值得分享和收藏的Bootstrap学习教程

    这绝对是一套值得分享和大家收藏的Bootstrap学习教程,完整的知识体系,系统的学习资料,帮助大家开启Bootstrap学习之旅,享受Bootstrap带给大家的奇妙乐趣...2016-05-14
  • AI:如何训练机器学习的模型

    这篇文章主要介绍了是如何进行机器学习的模型的训练,全文逻辑清晰,简单易懂,如果您正在学习机器学习那么可以参考下,说不定会有不一样的收货...2021-04-16
  • Android学习笔记之多界面切换实例

    一篇Android学习笔记之多界面切换实例,希望对各位朋友有所帮助。 用过VB 、 VC#的朋友都知道,在VB或VC#里要进行窗口(界面)切换很容易 例如在VB、C#里: 有 Fom1、...2016-09-20
  • php中的变量引用传值学习笔记

    引用:意思是将原始对象在内存中的地址传递给目标对象,就相当于原始对象和目标对象指向的是同一个内存地址。此时,如果对目标对象或者原始对象进行修改,内存中的数据也会改...2016-11-25
  • PHP中的cURL请求及示例学习笔记

    cURL是php中一个很强大的功能,可以模仿各种用户请求,如模仿用户登录,发送php cookie等等操作,下面我来整理一些相关的方法与各位同学看看 备注:使用curl_init函数,必须...2016-11-25
  • 那些年,我还在学习C# 学习笔记

    那些年学了ASP.NET后,才开始学习C#,说来也怪,怎么学了ASP.NET才来学习C#,其实没有什么的...2020-06-25
  • YII2 WIDGET的学习笔记

    CWidget是所有Widget的基类。CWidget是自包含组件,可以看出是MVC的简略版,CWidget相比Controller,既没有actions,也没有filters widget,英文意思为小工具,小挂件,在程序...2016-11-25
  • metasploit调用nexpose扫描学习笔记

    Metasploit是一个免费的、可下载的框架,通过它可以很容易地获取、开发并对计算机软件漏洞实施攻击。它本身附带数百个已知软件漏洞的专业级漏洞攻击工具 nexpose安...2016-11-25
  • php学习笔记之PHP扩展开发教程

    PHP扩展开发不是所有开发者都会操作的一个东西,下面我来演示一个关于PHP扩展开发实现过程,各位同学有需要可进入参考。 我们先假设需要这样一个扩展,提供一个叫tao_s...2016-11-25
  • Yii2学习笔记之汉化yii设置表单的描述

    小编推荐的这篇文章介绍了Yii2学习笔记之汉化yii设置表单的描述,非常实用,有兴趣的同学快来看看吧。 一:汉化框架&#8195;&#8195;框架汉化在这里设置,如果不生效,前台后...2017-07-06
  • php Builder建造器模式学习笔记

    星际里面有不少的任务关,也可以自己编辑地图,画面上有各种地形,建筑和部队,存在一个问题,初始化画面的流程很乱。待解决的问题:完成初始化画面的工作,同时尽量减少各种绘制...2016-11-25
  • php中session学习笔记

    Session指的就是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。从上述的定义中我们可以看到,Session实际上是一个...2016-11-25
  • 学习使用PHP数组

    PHP4.0中共有超过30个新的数组相关函数。其中很多通用函数答应你检查给定数组中是否存在特定对象、对数组元素计数、增加或删除元素,或对元素排序。 假如你有很大的...2016-11-25