PHP使用流类Stream读cUrl下载内容实例
使用 stream 的好处就是不会因为数据大小而占用大量的内存,现在我们来分享代码实例。
代码如下 | 复制代码 |
$url = 'http://www.google.com.tw' ; /* 建立接收的Temp File Stream */ $tmpfile = tmpfile (); $curl = curl_init (); /* 指定下载的的URL */ curl_setopt ( $curl , CURLOPT_URL, $url ); /* 指定存放的File Stream */ curl_setopt ( $curl , CURLOPT_FILE, $tmpfile ); /* 执行并取得状态*/ $status = curl_exec ( $curl ); curl_close ( $curl ); if (! $status ){ fclose ( $tmpfile ); exit ( 'error' ); } /* Temp File Stream 指标归零*/ fseek ( $tmpfile , 0); /*一次读取一行*/ while (( $line = fgets ( $tmpfile )) !== false ) { var_dump ( $line ); } /* 关闭Stream */ fclose ( $tmpfile ); |
本文以大富翁游戏为背景,综合运用jQuery和PHP知识,设计出以掷色子点数来达成抽奖的效果,当然抽奖概率是可控的,开发者可以将本实例稍作修改即可运用到网站中的抽奖活动场景中。
HTML
首先我们需要准备两粒色子和奖品素材,这些作者已经打包上传了,请大家放心下载。我们将在html页面中写下如下的html结构代码,.wrap用来放置色子和提示信息,#prize则是用来放置奖品的。
代码如下 | 复制代码 |
<div class="demo"> <div class="wrap"> <div id="msg"></div> <div id="dice"><span class="dice dice_1" id="dice1"></span> <span class="dice dice_6" id="dice2"></span></div> </div> <ul id="prize"> <li id="d_0"><img src="images/0.gif" alt="开始"></li> <li id="d_1"><img src="images/1.gif" alt="现金100元"></li> <li id="d_2"><img src="images/2.gif" alt="泰迪熊宝宝"></li> <li id="d_3"><img src="images/7.gif" alt="谢谢参与"></li> <li id="d_4"><img src="images/3.gif" alt="iphone 5s"></li> <li id="d_5"><img src="images/4.gif" alt="笔记本电脑"></li> <li id="d_6"><img src="images/7.gif" alt="谢谢参与"></li> <li id="d_7"><img src="images/5.gif" alt="单反相机"></li> <li id="d_8"><img src="images/6.gif" alt="轿车"></li> <li id="d_9"><img src="images/7.gif" alt="谢谢参与"></li> </ul> </div> |
CSS
我们要用CSS技术来将页面布局合理规范化,我们将奖品围成一个矩形,共10个位置,将两粒色子定位在矩形的中央,抽奖时可以直接点击中间的色子。这些我们可以用CSS的定位技术来实现页面布局。
代码如下 | 复制代码 |
.demo{width:650px; height:420px; margin:60px auto 10px auto; position:relative; } .wrap{width:200px; height:100px; position:absolute; margin-left:220px; margin-top:140px; z-index:1000;} #msg{display:none;width:50px; height:20px; padding:4px; background:#ffc; border:1px solid #fc9; text-align:center; color:#f30; font-size:18px; position:absolute; z-index:1001; right:-20px; top:-10px} .dice{width:90px; height:90px; display:block; float:left; background:url(dice.png) no-repeat; cursor:pointer} #dice_mask{width:200px; height:100px; background:#fff; opacity:0; position:absolute; top:0; left:0; z-index:999} .dice_1{background-position:-5px -4px} .dice_2{background-position:-5px -107px} .dice_3{background-position:-5px -212px} .dice_4{background-position:-5px -317px} .dice_5{background-position:-5px -427px} .dice_6{background-position:-5px -535px} .dice_t{background-position:-5px -651px} .dice_s{background-position:-5px -763px} .dice_e{background-position:-5px -876px} #prize{position:relative} #prize li{position:absolute; width:150px; height:112px; border:1px solid #d3d3d3} #d_0{left:0; top:0} #d_1{left:160px; top:0} #d_2{left:320px; top:0} #d_3{left:480px; top:0} #d_4{left:480px; top:128px} #d_5{left:480px; top:256px} #d_6{left:320px; top:256px} #d_7{left:160px; top:256px} #d_8{left:0; top:256px} #d_9{left:0; top:128px} .mask{opacity: 0.6; width:150px; height:112px; line-height:32px; background:#ffc; z-index:1001; position:absolute; top:0; left:0; text-align:center; font-size:16px} |
jQuery
我们使用jQquery来完成前端动作,包括掷色子动画,仿大富翁奖品逐步运动动画,其中有防重复点击知识、ajax交互知识,动画提示知识。整个 操作流程可简单概括为:点击色子->向dice.php发送ajax请求->完成掷色子动画->提示点数->逐步运动动画到最终 奖品位置停止->完成抽奖。
代码如下 | 复制代码 |
$(function(){ $("#dice").click(function(){ $("#prize li .mask").remove(); $(".wrap").append("<div id='dice_mask'></div>");//加遮罩 var dice1 = $("#dice1"); var dice2 = $("#dice2"); $.getJSON("dice.php",function(json){ var num1 = json[0]; var num2 = json[1]; diceroll(dice1,num1);//掷色子1动画 diceroll(dice2,num2);//掷色子2动画 var num = parseInt(num1)+parseInt(num2); $("#msg").css("top","-10px").fadeIn(500).text(num+'点').animate({top:'-50px'},'1000').fadeOut(500); roll(0, num);//逐步运动动画 }); }); }); |
函数diceroll()是一个色子运动动画,在本站前面的文章中已讲解过,就是通过jQuery的animate()实现的位移、延时、变化背景样式来实现的动画效果。
代码如下 | 复制代码 |
function diceroll(dice,num){ dice.attr("class","dice");//清除上次动画后的点数 dice.css('cursor','default'); dice.animate({left: '+2px'}, 100,function(){ dice.addClass("dice_t"); }).delay(200).animate({top:'-2px'},100,function(){ dice.removeClass("dice_t").addClass("dice_s"); }).delay(200).animate({opacity: 'show'},600,function(){ dice.removeClass("dice_s").addClass("dice_e"); }).delay(100).animate({left:'-2px',top:'2px'},100,function(){ dice.removeClass("dice_e").addClass("dice_"+num); dice.css('cursor','pointer'); }); } |
函数roll()至关重要,通过setInterval()设置一个间隔动画,每隔0.5秒时间执行一次。参数i代表初始位置,参数step代表需要执行 的步数,在本例中就是色子的点数,即需要走的步数。我们根据i给当前奖品加上.mask,当i的值与step相等时,停止动画,并且移除色子的遮罩(防止 重复点击)。
代码如下 | 复制代码 |
function roll(i,step){ var time = setInterval(function(){ if(i>9){ var t = i - 10; $("#d_"+t).append("<div class='mask'></div>"); $("#d_"+(t-1)+" .mask").remove(); } $("#d_"+i).append("<div class='mask'></div>"); $("#d_"+(i-1)+" .mask").remove(); if(i==step){ clearInterval(time); //如果到达指定位置则停止 $("#dice_mask").remove();//移除遮罩 } i++;//继续前进 },500); } |
PHP
dice.php需要做的事情有:根据配置好的奖品概率,得到总点数,根据总点数进行两粒色子的点数分配,最后返回给前端页面两粒色子的点数。
代码如下 | 复制代码 |
//设置中奖概率 $prize_arr = array( '2' => array('id'=>2,'v'=>10), '3' => array('id'=>3,'v'=>20), '4' => array('id'=>4,'v'=>5), '5' => array('id'=>5,'v'=>5), '6' => array('id'=>6,'v'=>20), '7' => array('id'=>7,'v'=>2), '8' => array('id'=>8,'v'=>3), '9' => array('id'=>9,'v'=>20), '10' => array('id'=>10,'v'=>0), '11' => array('id'=>11,'v'=>10), '12' => array('id'=>12,'v'=>5), ); foreach ($prize_arr as $key => $val) { $arr[$val['id']] = $val['v']; } $sum = getRand($arr); //根据概率获取奖项id,得到总点数 //分配色子点数 $arrs = array( '2' => array(array(1,1)), '3' => array(array(1,2)), '4' => array(array(1,3),array(2,2)), '5' => array(array(1,4),array(2,3)), '6' => array(array(1,5),array(2,4),array(3,3)), '7' => array(array(1,6),array(2,7),array(3,4)), '8' => array(array(2,6),array(3,5),array(4,4)), '9' => array(array(3,6),array(4,5)), '10' => array(array(4,6),array(5,5)), '11' => array(array(5,6)), '12' => array(array(6,6)) ); $arr_rs = $arrs[$sum]; $i = array_rand($arr_rs);//随机取数组 $arr_a = $arr_rs[$i]; shuffle($arr_a);//打乱顺序 echo json_encode($arr_a); |
函数getRand()用来计算概率
代码如下 | 复制代码 |
//计算概率 function getRand($proArr) { $result = ''; //概率数组的总概率精度 $proSum = array_sum($proArr); //概率数组循环 foreach ($proArr as $key => $proCur) { $randNum = mt_rand(1, $proSum); if ($randNum <= $proCur) { $result = $key; break; } else { $proSum -= $proCur; } } unset ($proArr); return $result; } |
有时为了安全及用户权限,我们不会直接把文件存在web路径用http给客户端下载,现在我们来讲讲如何php实现文件下载的原理及实例。
1、php下载原理图
2、文件下载源码:
<?php
$file_name="哈哈.jpg";//需要下载的文件
$file_name=iconv("utf-8","gb2312","$file_name");
$fp=fopen($file_name,"r+");//下载文件必须先要将文件打开,写入内存
if(!file_exists($file_name)){//判断文件是否存在
echo "文件不存在";
exit();
}
$file_size=filesize("a.jpg");//判断文件大小
//返回的文件
Header("Content-type: application/octet-stream");
//按照字节格式返回
Header("Accept-Ranges: bytes");
//返回文件大小
Header("Accept-Length: ".$file_size);
//弹出客户端对话框,对应的文件名
Header("Content-Disposition: attachment; filename=".$file_name);
//防止服务器瞬时压力增大,分段读取
$buffer=1024;
while(!feof($fp)){
$file_data=fread($fp,$buffer);
echo $file_data;
}
//关闭文件
fclose($fp);
?>
3、文件编码问题解决方法:
如果文件名是中文,php的函数不能识别中文文件名,一般如果程序编码为utf-8,php的函数比较古老,只能识别gb2312编码的中文,所以把中文用iconv(“原编码”,”要转成的编码”,”要转码的字符串”)函数可以转码。
比如,把一个字符串从utf-8转码为gb2312
$file_name=iconv(“utf-8”,”gb2312”,”$file_name”);
PHP下载远程文件原理
/**
* PHP下载远程文件到本地原理:通过PHP函数,先读取远程文件,然后在本地创建一个新的空文件,
* 然后将已读取的远程文件的内容写入到新创建的文件当中,这样就可以达到远程文件下载功能
* @author JackyLi
*
*/
class DownloadFile {
/**
* @param string $file 远程需要下载的文件
*/
public static function get_img_file($file) {
$targetDir = sys_get_temp_dir () . DIRECTORY_SEPARATOR . "plupload" . DIRECTORY_SEPARATOR;
if (! file_exists ( $targetDir )) { //检测临时下载目录是否存在,不存在,则新建一个
@mkdir ( $targetDir );
}
if (! $file) {
return false;
}
$ext = strrchr ( $file, "." ); //取扩展名
$filename = $targetDir . '/' . basename ( $file, $ext ) . date ( "YmdHis" ) . $ext; //需要保存的文件名称(带完整路径)
ob_start (); //开启output buffering
readfile ( $file ); //将文件读取buffering中
$img = ob_get_contents (); //将buffering中的数据保存到变量当中,方便后续操作
ob_end_clean (); //关闭output buffering
$fp2 = @fopen ( $filename, "a" ); //打开目标文件(马上被写入数据的文件)
fwrite ( $fp2, $img ); //写入数据到文件当中
fclose ( $fp2 ); //关闭文件句柄
//上面读取文件内容,可以直接用下面两行代替
// $file = file_get_contents($file);
// file_put_contents($filename,$file);
return true;
}
}
$download = new DownloadFile ();
$download->get_img_file ( 'http://news.sina.com.cn/c/2011-09-16/021323162600.shtml' );
Solr的版本升级较快,目前已经到5.x的版本,但是drupal的版本升级比较慢,因此关于Drupal升级使用solr高版本的问题,进展也比较慢,另外一个原因是Drupal的apachesolr模块是否支持也是一个问题,所以作者建议不要盲目的升级使用高版本,一定要测试之后才能在正式服务器上使用。
这次是参考网上的一些教程,把Apache Solr整合了中文分词,然后配合了Drupal的schema设置步骤,已经添加了自定义的中文分词器,对Drupal7以及中文分词做了支持。
Solr4.x增加了collection的概念,其实collection就是一个数据库的table的概念,这样一个core就可以有多个collection,solr的存储基本跟数据库就类似了。core等于数据库、collection等于数据表。
由于Jetty的版本不一样,导致配置文件的修改也有不同,因此jetty也做了适当修改,比如context.xml中把war文件改成了resourceBase的设置模式,以至于每次war文件解压不会覆盖work目录的修改。
第二个就是solr/drupal7/conf/solrconfig.xml文件中会引用很多相对路径的jar包文件,这些文件原本在solr- example中工作正常,但是单独拿出来就报错,因此作者把solr包里面的contrib文件夹复制到了solr(jetty)的根目录,并做了适当修改。
详细的使用还是跟之前的solr4z类似,只是这次只支持Drupal7,没办法支持Drupal6了。
#简单的启动请使用:(window/linux)
#端口号是:8983
java -jar start.jar
#使用辅助solrd (linux only)
#端口号: 8993
./solrd start #启动
./solrd startx #前端启动
./solrd stop #停止solr
Drupal里面设置url的时候,注意一下,直接使用corename/collection-name 就可以,具体参考Drupal大学这个问题:
在drupal中Solr4如何配置url?
批量添加数据和批量更新数据在可以为网站管理员节省不少时间,现在我们来学习一下用phpphp批量添加数据与批量更新数据的实现方法。
php如果要批量保存数据我们只要使用sql的insert into语句就可能实现数据批量保存了,如果是更新数据使用update set就可以完成更新了,操作方法都非常的简单,下面整理两个例子.
批量数据录入
设计方法:同时提交多条表单记录,为每一条记录设置相同的文本域名称,然后在表单处理页中,通过for循环来读取提取表单提交的数据,最后以数据的形式将数据逐条添加到数据库中.
其中,应用一个count()函数来获取数组中元素的个数.int count(mixed var);
表单提交页面,代码如下:
<form name="form1" method="post" action="index_ok.php">
<tr>
<td>商品名称</td>
<td>编号</td>
<td>单价</td>
<td>数量</td>
<td>产地</td>
<input name="data" type="hidden" value="<?php echo $data;?>">
</tr>
<tr>
<td><input name="sp_name[]" type="text" id="sp_name" size="15"></td>
<td><input name="sp_number[]" type="text" id="sp_number" size="10"></td>
<td><input name="price[]" type="text" id="price" size="8"></td>
<td><input name="counts[]" type="text" id="counts" size="8"></td>
<td><input name="address[]" type="text" id="address" size="15"></td>
</tr>
<input type="submit" name="submit" value="提交">
<input type="reset" name="reset" value="重置">
</form>
数据库连接页,代码如下:
<?php
$id=mysql_connect("localhost","root","password") or die('connection failed'.mysql_error());
if(mysql_select_db('mydatabase',$id))
echo "";
else
echo('select db failed:'.mysql_error());
?>
表单处理页,代码如下:
<?php session_start(); include("conn/conn.php");
if($submit==true){
for($i=0;$i<count($sp_name);$i++){
$path=$_POST["sp_name"][$i];
$path1=$_POST["sp_number"][$i];
$path2=$_POST["price"][$i];
$path3=$_POST["counts"][$i];
$path4=$_POST["address"][$i];
$query=mysql_query("insert into tb_products(sp_name,sp_number,price,counts,address,data) values('$path','$path1','$path2','$path3','$path4','$data');}
if($query==true){
echo"提交成功";
else
echo"提交失败";}
}
?>
批量更新数据
主要通过while, list(),each()函数来实理数据的批量更新,list()函数用于一次性为多个变量赋值,代码如下:
<?php session_start(); include("conn/conn.php");?>
<form name="form1" method="post" action="index_ok.php">
<?php $query="select * from tb_users";
$result=mysql_query($query);
if($result==true){
while($myrow=mysql_fetch_array($result)){
?>
<tr>
<td><input name="<?php echo $myrow[id];?> type="checkbox" value="<?php echo $myrow[id]; ?></td>
<td><?php echo $myrow[user];?></td>
<td><?php echo $myrow[popedom];?></td>
<td><?php echo $myrow[operation];?></td>
</tr>
<?php }} ?>
<tr>
<input type="submit" name="submit" value="激活">
<input type="submit" name="submit2" value="冻结">
</tr>
</form>
表单处理页,代码如下:
<?php session_start(); include("conn/conn.php")
if($submit=="激活"){
while(list($name,$value)=each($_POST)){
$result=mysql_query("update tb_user set operation='激活' where id='".$name."'");
if($result==true){
echo "<script> alert('激活成功');window.location.href='index.php';</script>";}}
if($submit2=="冻结"){
while(list($name,$value)=each($_POST)){
$result=mysql_query("update tb_user set operation='冻结' where id='".$name."'");
if($result==true){
echo "<script> alert('冻结成功');window.location.href='index.php';</script>";}}
}
?>
总结:心细的朋友会发现两个例子都有几个共同点,一个是表单from的表单名是以counts[]数组形式了,而在php处理接受页面都会使用for 或while来实现遍历了,下面我就简单的给大家分析这两个例子.
counts[]:这个在表单中是代表数组,如果你有10个表单那么我们name=counts[] 意思他们内个都是一样数组,知道这个是数组了就知道下面知道为什么会使用遍历了.
for或while:因为表单过来的是数组我们就可以遍历数组然后对数据进行保存了,如下代码:
while(list($name,$value)=each($_POST)){ 或
for($i=0;$i<count($sp_name);$i++){ 两个实现结果是一样的.
相关文章
Java8 实现stream将对象集合list中抽取属性集合转化为map或list
这篇文章主要介绍了Java8 实现stream将对象集合list中抽取属性集合转化为map或list的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-05- 这篇文章主要介绍了java8如何用Stream查List对象某属性是否有重复的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-11
- 有时为了网站安全和版权问题,会对自己写的php源码进行加密,在php加密技术上最常用的是zend公司的zend guard 加密软件,现在我们来图文讲解一下。 下面就简单说说如何...2016-11-25
解决:failed to open stream: No such file or directory in
本教程来给各位同学介绍failed to open stream: No such file or directory in解决办法,有需要了解的朋友可进入参考。 Warning: include_once(./include/main.i...2016-11-25- ps软件是现在很多人都会使用到的,HSL面板在ps软件中又有着非常独特的作用。这次文章就给大家介绍下ps怎么使用HSL面板,还不知道使用方法的下面一起来看看。  ...2017-07-06
- 这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下...2020-06-25
- 许多的朋友对于Plesk控制面板应用不是非常的了解特别是英文版的Plesk控制面板,在这里小编整理了一些关于Plesk控制面板常用的使用方案整理,具体如下。 本文基于Linu...2016-10-10
使用insertAfter()方法在现有元素后添加一个新元素
复制代码 代码如下: //在现有元素后添加一个新元素 function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement){ parent.appendChild(newEl...2014-05-31使用percona-toolkit操作MySQL的实用命令小结
1.pt-archiver 功能介绍: 将mysql数据库中表的记录归档到另外一个表或者文件 用法介绍: pt-archiver [OPTION...] --source DSN --where WHERE 这个工具只是归档旧的数据,不会对线上数据的OLTP查询造成太大影响,你可以将...2015-11-24- 大概有如下步骤 新建项目Bejs 新建文件package.json 新建文件Gruntfile.js 命令行执行grunt任务 一、新建项目Bejs源码放在src下,该目录有两个js文件,selector.js和ajax.js。编译后代码放在dest,这个grunt会...2014-06-07
如何使用php脚本给html中引用的js和css路径打上版本号
在搜索引擎中搜索关键字.htaccess 缓存,你可以搜索到很多关于设置网站文件缓存的教程,通过设置可以将css、js等不太经常更新的文件缓存在浏览器端,这样访客每次访问你的网站的时候,浏览器就可以从浏览器的缓存中获取css、...2015-11-24- 这篇文章主要介绍了使用list stream:任意对象List拼接字符串操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-09
jQuery 1.9使用$.support替代$.browser的使用方法
jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9。 如果要全面支持 IE,并混合...2014-05-31安装和使用percona-toolkit来辅助操作MySQL的基本教程
一、percona-toolkit简介 percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包括: 检查master和slave数据的一致性 有效地对记录进行归档 查找重复的索...2015-11-24- 举一个案例:复制代码 代码如下:<?phpclass Downfile { function downserver($file_name){$file_path = "./img/".$file_name;//转码,文件名转为gb2312解决中文乱码$file_name = iconv("utf-8","gb2312",$file_name...2014-06-07
- 一、下载 mysqlsla [root@localhost tmp]# wget http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz--19:45:45-- http://hackmysql.com/scripts/mysqlsla-2.03.tar.gzResolving hackmysql.com... 64.13.232.157Conn...2015-11-24
- 目前,JSON已经成为最流行的数据交换格式之一,各大网站的API几乎都支持它。我写过一篇《数据类型和JSON格式》,探讨它的设计思想。今天,我想总结一下PHP语言对它的支持,这是开发互联网应用程序(特别是编写API)必须了解的知识...2015-10-30
- 无限级分类在开发中经常使用,例如:部门结构、文章分类。无限级分类的难点在于“输出”和“查询”,例如 将文章分类输出为<ul>列表形式; 查找分类A下面所有分类包含的文章。1.实现原理 几种常见的实现方法,各有利弊。其中...2015-10-23
- C#注释的一些使用方法浅谈,需要的朋友可以参考一下...2020-06-25
- php类的使用实例教程 <?php /** * Class program for yinghua05-2 * designer :songsong */ class Template { var $tpl_vars; var $tpl_path; var $_deb...2016-11-25