Files
wy/ZeedFramework/library/Zeed/File.php
2026-01-07 11:40:41 +08:00

527 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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