Files
wy/ZeedFramework/library/Zeed/File.php

527 lines
14 KiB
PHP
Raw Normal View History

2026-01-07 11:40:41 +08:00
<?php
/**
* Zeed Platform Project
* Based on Zeed Framework & Zend Framework.
*
* BTS - Billing Transaction Service
* CAS - Central Authentication Service
*
* LICENSE
* http://www.zeed.com.cn/license/
*
* @category Zeed
* @package Zeed_File
* @copyright Copyright (c) 2010 Zeed Technologies PRC Inc. (http://www.zeed.com.cn)
* @author Zeed Team (http://blog.zeed.com.cn)
* @since 2010-6-30
* @version SVN: $Id: View.php 6709 2010-09-08 13:47:02Z xsharp $
*/
/**
* Zeed_File
*
* @todo 增加检测HTTP/FTP文件是否存在
*
* @category Zeed
* @package Zeed_Misc
* @subpackage Util
* @author xSharp ( GTalk/Email: xSharp@gmail.com | MSN: xSharp@msn.com )
*/
class Zeed_File
{
/**
* 大小写不敏感
*
* @param String $filename
* @return Array 返回文件列表数组
*/
public static function file_exists($filename)
{
return glob(dirname($filename) . '/' . sql_regcase(basename($filename)), GLOB_NOSORT);
}
/**
* 自动更名
*/
public static function autoRenameFile($filename, $i = 1)
{
if (file_exists($filename)) {
$pos = strrpos($filename, '.');
$fileExt = substr($filename, $pos);
$fileNameAbs = substr($filename, 0, $pos);
if (false != $pos = strrpos($fileNameAbs, '_')) {
$fileNameAbs = substr($fileNameAbs, 0, $pos);
}
$filename = $fileNameAbs . '_' . $i . $fileExt;
return self::autoRenameFile($filename, ++ $i);
} else {
return $filename;
}
}
/**
* 获取文件的内容, 支HTTP文件
*/
public static function file_get_contents($filename)
{
if (preg_match('/(http|https|ftp|file){1}(:\/\/)/i', $filename)) {
return self::getUrlFile($filename);
}
return file_get_contents($filename);
}
/**
* 获取HTTP文件数据
*
* @param String $filename
* @param String $retureType
* @return Zend_Http_Response|String|Null
*/
public static function getUrlFile($filename, $retureType = null)
{
try {
$client = new Zend_Http_Client($filename);
$response = $client->request();
return is_null($retureType) ? $response->getBody() : $response;
} catch (Exception $e) {
trigger_error($e->getMessage(), E_USER_NOTICE);
return null;
}
}
/**
* 获取URL Headers
*
* @param String $url
* @return Array|Null
*/
public static function getUrlHeader($url)
{
$fp = @fopen($url, 'r');
if ($fp) {
$meta = stream_get_meta_data($fp);
fclose($fp);
$headers = array();
while (list(, $v) = each($meta['wrapper_data'])) {
$_tmp = explode(':', $v);
$key = trim($_tmp[0]);
$val = trim(substr($v, strlen($_tmp[0]) + 1));
$headers[$key] = $val;
}
return $headers;
}
return null;
}
/**
* 检查URL是否可用(200)
*
* @param String $url_file
* @return Boolean
*/
public static function url_exists($url_file)
{
//检测输入
$url_file = trim($url_file);
if (empty($url_file)) {
return false;
}
$url_arr = parse_url($url_file);
if (! is_array($url_arr) || empty($url_arr)) {
return false;
}
//获取请求数据
$host = $url_arr['host'];
$path = $url_arr['path'] . "?" . $url_arr['query'];
$port = isset($url_arr['port']) ? $url_arr['port'] : "80";
//连接服务器
@$fp = fsockopen($host, $port, $err_no, $err_str, 10);
if (! $fp) {
return false;
}
//构造请求协议
$request_str = "GET " . $path . " HTTP/1.1\r\n";
$request_str .= "Host: " . $host . "\r\n";
$request_str .= "Connection: Close\r\n\r\n";
//发送请求
fwrite($fp, $request_str);
$first_header = fgets($fp, 1024);
fclose($fp);
//判断文件是否存在
if (trim($first_header) == "") {
return false;
}
if (! preg_match("/200/", $first_header)) {
return false;
}
return true;
}
/**
* 缓存网上的图片
*
* @param String $fileUrl
* @return String|Boolean 磁盘路径
*/
public static function snatchFile($fileUrl, $saveToDir)
{
// 处理空格
$fileUrl = str_replace(array(
' '), array(
'%20'), $fileUrl);
$saveToDir = (substr($saveToDir, - 1) == '/') ? $saveToDir : $saveToDir . '/';
$outputDir = $saveToDir;
$filename = md5($fileUrl);
$outputFile = $outputDir . substr($filename, 0, 2) . '/' . substr($filename, 2, 2) . '/' . $filename;
$failMeta = $outputFile . '-failmeta';
$failMetaData = array();
/**
* 文件已经存在,下列情况有效:
* 1.大于0
* 2.等于0,但是无 $failMeta
*/
if (file_exists($outputFile) or file_exists($failMeta)) {
if (file_exists($failMeta)) {
$failMetaData = unserialize(file_get_contents($failMeta));
// 失败超过3次不再抓取
if (count($failMetaData) >= 3) {
return false;
}
}
if (file_exists($outputFile)) {
return $outputFile;
}
}
/**
* 当Header Status不等于200时记录
*/
$requestObj = self::getUrlFile($fileUrl, 'obj');
if (! $requestObj instanceof Zend_Http_Response) {
$body = '';
$headers = array();
$code = '';
} else {
$body = $requestObj->getBody();
$headers = $requestObj->getHeaders();
$code = $requestObj->getStatus();
}
if ($code == '200') {
// 成功
if (file_exists($failMeta)) {
@unlink($failMeta);
}
return (self::file_put_contents($outputFile, $body)) ? $outputFile : false;
} else {
// 失败
$failMetaData[] = array(
'time' => date('Y-m-d H:i:s'),
'url' => $fileUrl,
'code' => $code,
'headers' => $headers);
self::file_put_contents($failMeta, serialize($failMetaData));
return $outputFile;
}
}
/**
* PHP内置 file_put_contents 函数的增强
* 增加了自动创建不存在的目录(路径)
*
* @see file_put_contents
* @param String $filename
* @param String $data
* @param String $mode
* @return Integer
*/
public static function file_put_contents($filename, $data, $mode = null)
{
$filename = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $filename);
$filename_dir = dirname($filename);
if (! is_dir($filename_dir)) {
Zeed_Util::mkpath($filename_dir);
}
if (is_null($mode)) {
$mode = 'w';
}
if (! file_exists($filename) || is_writable($filename)) {
if (! $handle = fopen($filename, $mode)) {
return false;
}
if (fwrite($handle, $data) === FALSE) {
return false;
}
fclose($handle);
@chmod($filename, 0666);
} else {
return false;
}
return true;
}
public static function writeSync($filename, $data)
{
self::file_put_contents($filename, $data);
}
/**
* Remove a file or dir,empty or nonempty
*
* @param String $f
* @return Boolean
*/
public static function unlink($f)
{
if (substr($f, - 1) == '/')
$folder = substr($f, 0, - 1);
if (is_dir($f) && ! is_link($f)) {
foreach (scandir($f) as $item) {
if (! strcmp($item, '.') || ! strcmp($item, '..'))
continue;
if (! Zeed_File::unlink($f . "/" . $item))
return false;
}
if (! @rmdir($f))
return false;
} else {
if (! @unlink($f))
return false;
}
return true;
}
/**
* Filename Security
*
* @access public
* @param string
* @return string
*/
public static function filename_security($str)
{
$bad = array(
"+",
"",
"",
"../",
"./",
"<!--",
"-->",
"<",
">",
"'",
'"',
'&',
'$',
'#',
'{',
'}',
'[',
']',
'=',
';',
'?',
"%20",
"%22",
"%3c", // <
"%253c", // <
"%3e", // >
"%0e", // >
"%28", // (
"%29", // )
"%2528", // (
"%26", // &
"%24", // $
"%3f", // ?
"%3b", // ;
"%3d"); // =
$repalce = array('_');
$str = stripslashes(str_replace($bad, $repalce, $str));
$c = Zeed_Util_Zh::isUGB($str);
if ($c != '') {
$str = Zeed_Util_Zh::pinyin(iconv($c, 'GBK', $str));
}
// 变态的字符统统去掉
$str = preg_replace('/[^\w\.\(\)\-\,]/', '_', $str);
return $str;
}
/**
* Check if $dir is a directory and it is empty
*
* @param string $dirname
* @return boolean
*/
public static function is_empty_dir($dirname)
{
$result = false;
if (is_dir($dirname)) {
$result = true;
$handle = opendir($dirname);
while (($name = readdir($handle)) !== false) {
if ($name != "." && $name != "..") {
$result = false;
break;
}
}
closedir($handle);
}
return $result;
}
/**
* @var finfo
*/
private static $_finfo;
/**
* @return finfo
*/
public static function finfo()
{
if (is_null(self::$_finfo)) {
if (DIRECTORY_SEPARATOR == '/') {
// *nix
$magicPath = self::findNixMagicFile();
} else {
// win
$magicPath = ZEED_PATH_DATA . '/mime/win/magic';
}
self::$_finfo = new finfo(FILEINFO_MIME, $magicPath);
}
return self::$_finfo;
}
/**
* Return information about a file
*
* @param String $file
* @return String
*/
public static function mime($file)
{
if (class_exists('finfo')) {
return self::finfo()->file($file);
} else {
if (DIRECTORY_SEPARATOR == '/') {
// *nix
$fileBin = '/usr/bin/file';
$magicPath = self::findNixMagicFile();
} else {
// win
$fileBin = PP_ROOT . '/../shell/win/file.exe';
$magicPath = ZEED_PATH_DATA . '/mime/win/magic';
}
$cmd = $fileBin . ' -i -b -m ' . $magicPath . ' ' . $file;
$info = array();
exec($cmd, $info);
return $info[0];
}
die('Get file\'s MimeType Fail.');
}
/**
* @return string
*/
private static function findNixMagicFile()
{
$magicPath = ZEED_PATH_DATA . '/mime/linux/magic';
$searchpaths = array();
$searchpaths[] = '/usr/share/file/magic'; // debian
$searchpaths[] = '/usr/share/magic'; // centos
foreach ($searchpaths as $_spath) {
if (file_exists($_spath)) {
$magicPath = $_spath;
break;
}
}
return $magicPath;
}
/**
* 直接从内容中获取其MIMETYPE信息
*
* @param string $buffer
* @return string
*/
public static function mimeBuffer($buffer)
{
return self::finfo()->buffer($buffer);
}
/**
* Return icon url of a certain file
*
* @param String $filename
* @param String $size
* @return String
*/
public static function icon($filename, $size = "S")
{
$ext = substr($filename, strrpos($filename, '.') + 1);
$icon = "/static/common/icons/" . $ext . ".gif";
if (file_exists(ZEED_PATH_VIEW . $icon)) {
return $icon;
}
return "/static/common/icons/default.icon.gif";
}
/**
* 获取文件行数
*
* @param string $filename
* @return integer file line number
*/
public static function getFileLines($filename)
{
if (!is_readable($filename)) {
throw new Zeed_Exception("file $filename can not readable.");
}
$lineNum = 0;
if ($stream = fopen($filename, 'r')) {
while (!feof($stream)) {
fgets($stream); // Burn a line so feof will work correctly.
$lineNum++; // This will increment even for blank lines and even if the very last line is blank.
}
}
return $lineNum;
}
}
// End ^ LF ^ UTF-8