这次的例子是把订单的数据保存起来,一般是用数据库来进行数据的存储最好,但是今天目的是为了学习读写文件,所以这次把数据存在文件里。

读写文件有一般有三个步骤:

  1)打开文件。如果文件不存在,需要先创建它。

  2)读取/写入数据。

  3)关闭文件。

1.使用fopen()打开文件。

  $fp = fopen("$DOCUMENT_ROOT/../orders/orders.txt", "ab");

fopen()返回一个文件指针给$fp,读写文件时需要使用这个变量。

  调用fopen()通常使用2个参数。第一个参数指定文件名,第二个参数指定打开文件的方式。

  php有个内置变量$_SERVER['DOCUMENT_ROOT']指向web服务器的根目录,同表单数据一样,这个变量也有3种访问方法,这里将$_SERVER['DOCUMENT_ROOT']赋给$DOCUMENT_ROOT以方便访问。“..“表示文档的父目录,出于安全原因,将要读写的文件放在web根目录的外面(这个安全原因我也不太清楚,可能以后书里会提到了)。

  a-追加模式,从文件末尾开始追加,如文件不存在,先创建这个文件。b-二进制模式,windows系统下会区分二进制文件和文本文件,为了获得最大的可移植性,推荐使用这项。更多其他模式可以查看文档。

  打开文件时,可能会遇到的错误是试图打开一个没有权限进行读写操作的文件(通常会在unix系统中遇到)。这时可以创建一个全局可写的目录来存储文件:

  mkdir ~/orders

  chmod 777 ~/orders

  如果fopen()调用失败,会返回false,并且通过@抑制错误信息,反馈给用户友好的错误提示。@只是简单的错误处理方法,以后会学到更好的错误处理的方法。

@ $fp = fopen("$DOCUMENT_ROOT/../orders/orders.txt", "ab");
if(!$fp){
echo "<p><strong>您的订单暂时不能处理,请稍后重试</strong></p></body></html>"; //在退出脚本前补全html标记,生成有效的html
exit;
}

  2.写文件。

   写文件可以使用fwrite()或fputs(),fputs()是fwrite()的别名。

   fwrite($fp, $outputstring); //将$outputstring的字符串写入到$fp指向的文件中。

   fwrite()还有第三个参数,是可选的,表示写入的最大字符数。在使用二进制模式的写操作时,使用第三个参数可以避免一些跨平台的兼容性问题。

   fwrite($fp, $outputstring, strlen($outputstring));

  3.关闭文件。

   fclose($fp); //成功返回true,反之false

  现在可以把表单数据保存到文件中了,最新的processorder.php:

<?php
//php每一行要用;结尾
$tireqty = $_POST['tireqty'];
$oilqty = $_POST['oilqty'];
$sparkqty = $_POST['sparkqty'];
$address = $_POST['address'];
$totalqty = 0;
$totalamount = 0.00;
$date = date("H:i, jS F Y"); define('TIREPRICE', 100);
define('OILPRICE', 10);
define('SPARKPRICE', 4); $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>订单处理页</title>
</head>
<body>
<h1>汽车配件网店</h1>
<h2>订单</h2>
<?php
if(empty($tireqty) && empty($oilqty) && empty($sparkqty)){
echo "<p style='color:red'>您没有选购商品</p>";
exit;
}
if(is_numeric($tireqty) && is_numeric($oilqty) && is_numeric($sparkqty)){ $totalqty = $tireqty + $oilqty + $sparkqty;
$totalamount = $tireqty * TIREPRICE + $oilqty * OILPRICE + $sparkqty * SPARKPRICE; echo "<p>订单处理时间:".date("H:i, jS F Y")."</p>"; //php用“.”连接字符串
echo "购买总数:$totalqty <br>";
echo "购买总额:¥$totalamount<br>";
}else{
echo "<p style='color:red'>参数必须为数字</p></body></html>";
exit;
} //保存订单数据
@ $fp = fopen("$DOCUMENT_ROOT/../orders/orders.txt", "ab");
if(!$fp){
echo "<p><strong>您的订单暂时不能处理,请稍后重试</strong></p></body></html>"; //在退出脚本前补全html标记,生成有效的html
exit;
} //将每一个订单拼成一行数据
$outputstring = $date."\t".$tireqty."个轮胎\t".$oilqty."桶汽油\t".$sparkqty."个火花塞\t\$".$totalamount."\t".$address."\n";
fwrite($fp, $outputstring, strlen($outputstring));
fclose($fp); echo "<p>订单已存储</p>";
?>
</body>
</html>

  4.读文件。

     以只读模式打开文件:$fp = fopen("$DOCUMENT_ROOT/../orders/orders.txt", "rb");

   feof()作为文件结束的测试条件,fgets()从文件中每次读取一行。

   员工查看订单的页面vieworders.php:

<?php
$DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>订单查看页</title>
</head>
<body>
<h1>汽车配件网店</h1>
<h2>查看订单</h2>
<?php
@ $fp = fopen("$DOCUMENT_ROOT/../orders/orders.txt", "rb"); if(!$fp){
echo "<p><strong>暂时还没有订单,请稍后重试。</strong></p></body></html>";
exit;
}
while (!feof($fp)) {
$order = fgets($fp, 999);
echo $order."<br/>";
}
?>
</body>
</html>

     上面脚本的代码几乎可以用readfile("$DOCUMENT_ROOT/../orders/orders.txt")这一句来替代。

   读取整个文件的函数:readfile()将打开文件,将文件内容输出到标准输出(浏览器)中,然后再关闭文件。但是由于“\n"在浏览器中不能显示为换行,所以还是用上面的代码显示比较清晰。

  5.文件锁定。

     在读写文件时,锁定该文件,以避免并发带来的问题。

   flock(resource fp, int operation [, int & wouldblock])

   operation有几个值:

    LOCK_SH 读操作锁定,文件可以共享,其他人可以读该文件

      LOCK_EX  写操作锁定

      LOCK_UN  释放已有的锁定

    LOCK_NB   防止在请求加锁时发生阻塞

   所以对刚才的脚本改进一下,processorder.php:

flock($fp, LOCK_EX);
fwrite($fp, $outputstring, strlen($outputstring));
flock($fp, LOCK_UN);
fclose($fp);

    vieworders.php:  

     flock($fp, LOCK_SH);
while (!feof($fp)) {
$order = fgets($fp, 999);
echo $order."<br/>";
}
flock($fp, LOCK_UN);
fclose($fp);

  

   

【自学php】第三天 - 读写文件的更多相关文章

  1. 孤荷凌寒自学python第三十三天python的文件操作初识

     孤荷凌寒自学python第三十三天python的文件操作初识 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天开始自学python的普通 文件操作部分的内容. 一.python的文件打开 ...

  2. 孤荷凌寒自学python第三十七天python的文件与内存变量之间的序列化与反序列化

    孤荷凌寒自学python第三十七天python的文件与内存变量之间的序列化与反序列化 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.什么是序列化与反序列化 序列化是指将内存中的数据进行指 ...

  3. 孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容

     孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.打开文件后,要务必记得关闭,所以一般的写法应当 ...

  4. 孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习

     孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.close() 当一个file对象执行此方法时,将关闭当前 ...

  5. php中并发读写文件冲突的解决方案

    在这里提供4种高并发读写文件的方案,各有优点,可以根据自己的情况解决php并发读写文件冲突的问题. 对于日IP不高或者说并发数不是很大的应用,一般不用考虑这些!用一般的文件操作方法完全没有问题.但如果 ...

  6. Inno Setup 如何读写文件

    软件安装的实质就是拷贝,对于简单的打包当然不需要考虑修改某(配置)文件.通过inno修改文件的目的在于把安装时相关信息写入文件中,提供其它应用的读取,而这些信息也只能在安装时才能确定,比如安装用户选择 ...

  7. JAVA基础学习之流的简述及演示案例、用缓冲区方法buffer读写文件、File类对象的使用、Serializable标记接口(6)

    1.流的简述及演示案例输入流和输出流相对于内存设备而言.将外设中的数据读取到内存中:输入将内存的数写入到外设中:输出.字符流的由来:其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表. ...

  8. php中并发读写文件冲突的解决方案(文件锁应用示例)

    PHP(外文名: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,入门门槛较低,易于学习,使用广泛,主要适 ...

  9. Java读写文件方法总结

    Java读写文件方法总结 Java的读写文件方法在工作中相信有很多的用处的,本人在之前包括现在都在使用Java的读写文件方法来处理数据方面的输入输出,确实很方便.奈何我的记性实在是叫人着急,很多时候既 ...

随机推荐

  1. table中td,th不能设置margin

    首先,我们需要知道的是:我们可以对表格table设置margin,而不能设置padding;对单元格td设置padding,而不能设置margin.所以说,我们不能对单元格td设置margin属性来调 ...

  2. css 兼容小三角

    <!DOCTYPE><html ><head><meta http-equiv="Content-Type" content=" ...

  3. 【ecos学习5】redboot 加载运行hello world

    背景: 从主机 192.168.2.14 IP,下载bin文件hello到ecos. redboot>load -v -h 192.168.2.14 hello Using default pr ...

  4. View的工作原理(二)——layout

    1.当View的measure被确定后,会调用ViewGroup的layout方法,之后使用onLayout方法(同样也是系统未自动重写,要我们自己完成)遍历子View(根Measure的形式是一样得 ...

  5. python用法——Mixin

    在读werkzeug和flask的源码中,经常能遇到类名中有mixin这个东西.这个东西的用法让我想到了java中的接口名有able的用法.今天我就来看了看这个mixin是什么东西. 学习了pytho ...

  6. 使用Hashtable和List结合拼json数据

    在做项目的时候,有时候需要向页面返回一个特定的json类型的数据,一般情况下会有下面的方法进行拼接: public String chongzhiList() throws Exception { L ...

  7. EasyUI两种动态添加tab Iframe页面的方法

    /** 动态添加tab-----方式一 **/ function addIframeTab(titleTxt,href,icon) { $('#mytabs').tabs('addIframeTab' ...

  8. 【BZOJ 1088 扫雷Mine】模拟

    http://www.lydsy.com/JudgeOnline/problem.php?id=1088 2*N的扫雷棋盘,第二列的值a[i]记录第 i 个格子和它8连通的格子里面雷的数目. 第一列的 ...

  9. virtualbox 复制多个虚拟机 (宿主机redhat)

    我用VirtualBox做了一个winxp虚拟镜像. 想实现不重新安装而直接复制几个,也就是同时装载几个虚拟机. 但是直接复制已安装好机子的vdi文件,系统会报uuid已存在的错误. 所以,就需要修改 ...

  10. [网络分析]WEBQQ3.0协议分析---good good study

    声明:研究学习使用,严禁商业化~~噗嗤,估计也没有商业化的 本文地址:http://blog.csdn.net/sushengmiyan/article/details/11906101 作者:sus ...