PHP文件核心编程

Jackey PHP 2,909 次浏览 , 没有评论

想一想:什么是文件?

Linux文件

  • 定义:存储在某种设备中的一段数据流
  • 在Linux中,几乎一切都是文件
  • 文件类型:普通文件、链接文件、目录文件、设备文件
  • 设备文件:/dev/tty, /dev/null, /dev/zero
  • 每个文件对应一个“inode”数据

inode包含什么内容?

  • 文件的字节数
  • 文件的uid和gid
  • 文件的读、写、执行权限
  • 文件的时间戳:ctime,mtime,atime
  • 链接数:有多少文件名指向这个inode
  • 文件数据block的位置

ext3文件系统特点

  • ext3是一种日志式文件系统
  • 最长文件名:255字节
  • 最大文件大小:16GB-64T(取决于块尺寸)
  • 最大卷容量:2TB-32TB
  • 最大文件数量:可变

XFS文件系统特点

  • XFS是一种日志式文件系统,最早1993年
  • 最长文件名:255字节
  • 最大文件大小:8 exbibytes减1字节
  • 最大卷容量:16 exabytes
  • 最大文件数量:可变
  • 已经在CenOS7上作为默认文件系统

文本文件和二进制文件有什么不同?

  • 文本文件是基于字符编码的文件
  • 除了文本文件以外的文件称为二进制文件
  • 二进制文件编码是变长的,灵活利用率高
  • 两者读写差别仅体现在回车换行符的处理上
  • 文本文件是一种特殊的“二进制文件”

文件的打开方式有哪些?

$handle = fopen('test.txt', 'r');

  • r 只读方式打开,将文件指针指向文件头
  • r+ 读写方式打开,将文件指针指向文件头
  • w 写入方式打开,将文件指针指向文件头(源文件会被清空)
  • w+ 读写方式打开,将文件指针指向文件头(同上)
  • a 写入方式打开,将文件指针指向文件末尾
  • a+ 读写方式打开,将文件指针指向文件末尾
  • x 创建并以写入方式打开,将文件指针指向文件头(原有文件不能存在)
  • x+ 创建并以读写方式打开,其他的行为和x一样(同上)
  • c 写入方式打开,将文件指针指向文件头(原有文件会被覆盖)
  • c+ 读写方式打开,将文件指针指向文件头(同上)

文件的打开方式的特殊标记

1.标记('t')可以将\n转换为\r\n(windows)
$handle = fopen("test.txt", "wt");
2.标记('b')来强制使用二进制模式
$handle = fopen("test.txt", "rb");

把多个文件合并为一个文件

$fh = fopen('dest.txt', '?');
$fh1 = fopen('file1.txt', '?');
$fh2 = fopen('file2.txt', '?');

练习:用pack创建二进制文件
1.用pack创建二进制文件“my.db”,文件里面存入的内容为:姓名、QQ号、email。
$fh = fopen('./my.db', 'w');
$name = pack('A20', 'zsf'); //A20的意思是将字符串以空格填满
$age = pack('S', 255);
$email = pack('a20', 'zhangsf@qq.com'); //a20的意思是将字符串以null填充
fwrite($fh, $name . $age . $email);

或者

$data = pack('A20Sa20', 'zwf', 1219, 'wf@qq.com');
fwrite($fh, $data);

2.用unpack把以上文件内容读取出来。

$data = file_get_contents('my.db');
$items = unpack('A20name/Sage/a20email', $data);
print_r($items);

怎么判断是不是PNG图片?

  1. <FrontBlock>
  2. <Pattern>
  3. <Bytes>89504E470D0A1A0A0000000D49484452</Bytes>
  4. <ASCII>.PNG........IHDR</ASCII>
  5. <Pos>0</Pos>
  6. </Pattern>
  7. </FrontBlock>

 

文件指针的定位操作

  • fseek() 在文件指针中定位
  • ftell() 返回文件指针读/写的位置
  • rewind() 倒回文件指针的位置
  • feof 测试文件指针是否到了文件结束的位置

随机读写文件的应用

  • 分析读取特定的二进制文件的内容,如纯真IP库、QQ本地消息、图片元数据信息等
  • 创建特定的二进制文件,如pdf,word,chm等
  • 对大文件进行切割,如视频切割器
  • 创建自定义的二进制文件,实现自己的独特需求,如设计自己的数据库文件

PHP中XML处理方式比较

  • DOM:一次性将xml载入内存,内存问题需要注意
  • SimpleXML:小文件可以选择它,不支持命名空间。
  1. <?php
  2. $string = <<<XML
  3. <?xml version='1.0'?>
  4. <document>
  5.   <cmd>login</cmd>
  6.   <login>imdonkey</login>
  7. </document>
  8. XML;
  9.  
  10. $xml = simplexml_load_string($string);
  11. pring_r($xml);

 

  • XMLReader:边读边操作,“拉取”模型
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <collection>
  3. <cd>
  4. <title type="hk">港台明星</title>
  5. <artist>刘德华</artist>
  6. <tear>1995</year>
  7. </cd>
  8. <cd>
  9. <title>大陆演员</title>
  10. <artist>范冰冰</artist>
  11. <tear>1997</year>
  12. </cd>
  13. </collection>

 

  1. $reader->open('collection.xml', 'utf-8');
  2. while($reader->read()){
  3. if($reader->name=="cd" && $reader->nodeType==XMLReader::ELEMENT){
  4. $item=[];
  5. while($reader->nodeType!=XMLReader::ELEMENT)continue;
  6. $name=$reader->name;
  7. $value=$reader->readString();
  8. // echo $key=$reader->getAttribute('name');
  9. $item[$name]=$value;
  10. }
  11. $items[]=$item;
  12. }
  13. $reader->close();
  14. print_r($items);

 

  • XML Parser:SAX模型是一个“推送”模型
  1. <?php
  2. $file = "collection.xml";
  3. $depth = [];
  4.  
  5. function startElement($parser, $name, $attrs)
  6. {
  7. global $depth
  8. print_r($attrs);
  9. }
  10. function endElement($parser, $name)
  11. {
  12. global $depth;
  13. }
  14. function data($parser, $data)
  15. {
  16. var_dump($data);
  17. }
  18.  
  19. $xml_parser = xml_parser_create('UTF-8');
  20. xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 1);
  21. xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
  22.  
  23. xml_set_element_handler($xml_parser, "startElement", "endElement");
  24. xml_set_character_data_handler($xml_parser, "data");
  25.  
  26. $fp = fopen($file, "r");
  27.  
  28. while($data = fread($fp, 4096)){
  29. if(!xml_parser($xml_parser, $data, feof($fp))){
  30. die(sprintf("XML error: %s at line %d",
  31. xml_get+current_line_number(xml_parser)));
  32. }
  33. }
  34. xml_parser_free($xml_parser);

 

PHP中JSON的处理

一下符合JSON标准的有?
A:{a:'abc'}
B: {'a':'abc'}
C: {"a":"abc",}
D:{"a":"abc"}

  • jsson_encode 目前只能处理UTF-8编码的数据
  • JSON_UNESCAPED_UNICODE 让JSON更懂中文
  • 解析出错,看json_last_error()返回的错误
  • JSON格式是灵活开放的,特殊情况可以用sprintf来自己组装或者解析JSON字符串

$format = '["%s",%d,%b]';
echo $jsonstr = sprintf($format, '张三丰', 16, false);
$json = json_decode($jsonstr);
print_r($json);
echo json_last_error_msg();

  1. <?php
  2. function encode($data){
  3. switch ($type = gettype($data)){
  4. case 'NULL':
  5. return 'null';
  6. case 'boolean':
  7. return ($data ? 'true' : 'false');
  8. case 'integer':
  9. case 'double':
  10. case 'float':
  11. return $data;
  12. case 'string':
  13. return '"' . addcslashes($data, "\r\n\t\"") . '"';
  14. case 'object':
  15. $data = get_object_vars($data);
  16. case 'array':
  17. $count = 0;
  18. $indexed = [];
  19. $associative = [];
  20. foreach ($data as $key => $value){
  21. if($count !== NULL && (gettype($key) !== 'integer' || $count++ !== $key)) {
  22. $count = NULL;
  23. }
  24. $one = encode($value);
  25. $indexed[] = $one;
  26. $associative[] = encode($key) . ':' . $one;
  27. }
  28. if ($count !== NULL) {
  29. return '[' . implode(',', $indexed) . ']';
  30. } else {
  31. return '{' . implose(',', $associative) . '}';
  32. }
  33. default:
  34. return '';
  35. }
  36. }

 

json_encode的参数

  • JSON_HEX_TAG 所有的 < 和 > 转换成 \u003c 和 \u003e
  • JSON_HEX_AMG 所有的 & 转换成 \u0026
  • JSON_HEX_APOS 所有的 ' 转换成 \u0027
  • JSON_HEX_QUOT 所有的 " 转换成 \u0022
  • JSON_FORCE_OBJECT 强制使用索引数组输出
  • JSON_NUMERIC_CHECK 将所有数字字符串编码成数字
  • JSON_BIGINT_AS_STRING 将大数字编码成原始字符原来的值
  • JSON_PRETTY_PRINT 用空白字符格式化返回的数据
  • JSON_UNESCAPED_SLASHES 不要编码 /
  • JSON_UNESCAPED_UNICODE 以字面编码多字节Unicode字符(默认是编码成 \uXXXX)

CSV文件处理

fputcsv()
fgetcsv()

  1. <?php
  2. $list = array(
  3. array('aaa', 'bbbb', 'ccc', 'ddd'),
  4. array('123', '456', '789'),
  5. array('"aaa"', '"bbb"'),
  6. );
  7.  
  8. $fp = fopen('file.csv', 'w');
  9. foreach($list as $fields) {
  10. fputcsv($fp, $fields, ';'); //默认 , 号
  11. }
  12.  
  13. fclose($fp);

fopen 还能打开什么?

fopen('php://stdout', 'w');

  • file:// 访问本地文件系统
  • http:// 访问HTTP(S) 网址
  • ftp:// 访问FTP(S) URLs
  • php:// 访问各个输入/输出流(I/O streams)
  • zlib:// 压缩流
  • http://php.net/manual/zh/wrappers.php

<?php
fputs(STDOUT, strtoupper(fgets(STDIN)));

//echo stroupper(fgets(STDIN));
//fputs(STDOUT, 'hello');

//$fp1 = fopen('php://stdin', 'r');
//echo strtoupper(fgets($fp1));

//$fp2 = fopen('php://stdout', 'w');
//fputs($fp2, 'hello');

如何实现超大文件上传?

  • 客户端控件:需要本地安装指定控件
  • 采用 swfUpload、uploadify 等Flash组件
  • 用XMLHttpRequest 实现大文件上传和断点续传

XMLHttpRequest 2.0 的新特性

  • 可以上传文件
  • 可以设置HTTP请求的时限
  • 可以使用FormData对象管理表单数据
  • 可以请求不同域名下的数据(跨域请求)
  • 可以获取服务器端的二进制数据
  • 可以获取数据传输的进度信息

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

Go