php 调用 webservice 中文乱码解决方案

 更新时间:2016年11月25日 16:25  点击:1470

由于工作的需要,帮我的同事阿韬测试一下.net的webservice在PHP下的应用.于是开始上网找资料,发现很多php教程er都是用nusoap.于是下载一个回来.用它自带的例子修改一下.可在文章的后面的附件中找到下载地址.
代码如下:

 

<?php
require_once('../nusoap/lib/nusoap.php');
$client = new soapclient('http://localhost/TestService/Service1.asmx?WSDL', true);
$err = $client->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
}
// Doc/lit parameters get wrapped
$param = array('str' => 'China');
$result = $client->call('HelloWorld', array('parameters' => $param), '', '', false, true,'document','encoded');
// Check for a fault
if ($client->fault) {
echo '<h2>Fault</h2><pre>';
print_r($result);
echo '</pre>';
} else {
// Check for errors
$err = $client->getError();
if ($err) {
  // Display the error
  echo '<h2>Error</h2><pre>' . $err . '</pre>';
} else {
  // Display the result
  echo '<h2>Result</h2><pre>';
  print_r($result);
  echo '</pre>';
}
}
echo '<h2>Request</h2><pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2><pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
echo '<h2>Debug</h2><pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';
?>


如果我的webservice返回的内容中没有中文的话,则很简单就上面的例子就成功了.但是一个新的问题出现了,如果我的webservice中有中文的话,返回的值就变成了乱码.查看了一下response的结果,是正确的.应该是用nusoap处理的时候出现了问题.
由于我没有安装PHP断点调试工具(其实我都不知道有没有这个工具).所以只能一个方法,一个方法看.看了一天,终于看完了.更改了nusoap.php两个地方就OK了.
更改的地方:
86行的:    var $soap_defencoding = 'UTF-8';
4998行的:    var $decode_utf8 = false;
=======================================================================
不更改也可以,不过在调用的时候就必须指定编码
$client = new soapclient('http://localhost/TestService/Service1.asmx?WSDL', true);
$client->soap_defencoding = 'UTF-8';
$client->soap_defencoding = 'UTF-8';
这样的效果也是一样的。
=======================================================================
如果请求的时候参数有中文,只需用post或者get的方式传送就可以了.
如果需要将带有中文的参数写在代码里面,则需要把编码转成UTF8.可能参考附件.

 

附件:
nusoap源文件: http://www.cnblogs.com/Files/coolstr/nusoap.zip
各种编码转换源文件: http://www.cnblogs.com/Files/coolstr/chinese.zip

 

 

fopen实现代码:

fopen() 函数打开文件或者 URL。

如果打开失败,本函数返回 FALSE。


 代码如下:

<?php教程
$handle = fopen ("http://www.example.com/", "rb");
$contents = "";
while (!feof($handle)) {
$contents .= fread($handle, 8192);
}
fclose($handle);
?>

 代码如下:
<?php
// 对 PHP 5 及更高版本
$handle = fopen("http://www.example.com/", "rb");
$contents = stream_get_contents($handle);
fclose($handle);
?>

参数 描述
filename 必需。规定要打开的文件或 URL。
mode 必需。规定要求到该文件/流的访问类型。可能的值见下表。
include_path 可选。如果也需要在 include_path 中检索文件的话,可以将该参数设为 1 或 TRUE。
context 可选。规定文件句柄的环境。Context 是可以修改流的行为的一套选项。

mode 参数的可能的值

mode 说明
"r" 只读方式打开,将文件指针指向文件头。
"r+" 读写方式打开,将文件指针指向文件头。
"w" 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
"w+" 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
"a" 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
"a+" 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
"x"

创建并以写入方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。

这和给底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。

此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。

"x+"

创建并以读写方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。

这和给底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。

此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。

2.curl实现代码:
 代码如下:

<?php
function _url($Date){
$ch = curl_init();
$timeout = 5;
curl_setopt ($ch, CURLOPT_URL, "$Date");
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$contents = curl_exec($ch);
curl_close($ch);
return $contents;
}
$pageURL="http://www.baidu.com";
$contents=_url($pageURL);
?>

curl_close — 关闭一个curl会话
curl_copy_handle — 拷贝一个curl连接资源的所有内容和参数
curl_errno — 返回一个包含当前会话错误信息的数字编号
curl_error — 返回一个包含当前会话错误信息的字符串
curl_exec — 执行一个curl会话
curl_getinfo — 获取一个curl连接资源句柄的信息
curl_init — 初始化一个curl会话
curl_multi_add_handle — 向curl批处理会话中添加单独的curl句柄资源
curl_multi_close — 关闭一个批处理句柄资源
curl_multi_exec — 解析一个curl批处理句柄
curl_multi_getcontent — 返回获取的输出的文本流
curl_multi_info_read — 获取当前解析的curl的相关传输信息
curl_multi_init — 初始化一个curl批处理句柄资源
curl_multi_remove_handle — 移除curl批处理句柄资源中的某个句柄资源
curl_multi_select — Get all the sockets associated with the cURL extension, which can then be "selected"
curl_setopt_array — 以数组的形式为一个curl设置会话参数
curl_setopt — 为一个curl设置会话参数
curl_version — 获取curl相关的版本信息
curl_init()函数的作用初始化一个curl会话,curl_init()函数唯一的一个参数是可选的,表示一个url地址。
curl_exec()函数的作用是执行一个curl会话,唯一的参数是curl_init()函数返回的句柄。
curl_close()函数的作用是关闭一个curl会话,唯一的参数是curl_init()函数返回的句柄。

编码转换函数
 代码如下:

$html = file_get_contents(http://mb.111cn.net);
$html = iconv( "Big5", "UTF-8//IGNORE" , $html); //转化编码方式为UTF8
print $html;
$htm = file("http://s.111cn.net");
$h = "";
foreach($htm as $value)
{
$h.= iconv( "GB2312", "utf-8//IGNORE" , $value);
}
print_r($h);

file_get_contents(path,include_path,context,start,max_length)

参数 描述
path 必需。规定要读取的文件。
include_path 可选。如果也想在 include_path 中搜寻文件的话,可以将该参数设为 "1"。
context

可选。规定文件句柄的环境。

context 是一套可以修改流的行为的选项。若使用 null,则忽略。

start 可选。规定在文件中开始读取的位置。该参数是 PHP 5.1 新加的。
max_length 可选。规定读取的字节数。该参数是 PHP 5.1 新加的。

另一种打开网页的方法
 代码如下:

<?php
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: enrn" .
"Cookie: foo=barrn"
)
);
$context = stream_context_create($opts);
/* Sends an http request to www.111cn.net

with additional headers shown above */
$fp = fopen('http://www.baidu.com', 'r', false, $context);
fpassthru($fp);
fclose($fp);
?>

memcache的官方主页:php教程.net/package/memcache">http://pecl.php.net/package/memcache
memcached的官方主页:http://pecl.php.net/package/memcached

以下是我安装Memcached版本的PHP模块的过程记录:

wget http://download.tangent.org/libmemcached-0.48.tar.gz
tar zxf libmemcached-0.48.tar.gz
cd libmemcached-0.48
./configure --prefix=/usr/local/libmemcached --with-memcached
make
make install

wget http://pecl.php.net/get/memcached-1.0.2.tgz
tar zxf memcached-1.0.2.tgz
cd memcached-1.0.2
/usr/local/webserver/php/bin/phpize
./configure --enable-memcached --with-php-config=/usr/local/webserver/php/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached
make
make install

在php.ini中加入
extension=memcached.so
完成

另:
在安装libmemcached时,如果只用./configure,可能会提示:
checking for memcached… no
configure: error: “could not find memcached binary”


安装Memcached版本的PHP模块

wget http://download.tangent.org/libmemcached-0.35.tar.gz
tar zxf libmemcached-0.35.tar.gz
cd libmemcached-0.35
./configure
make
make install

wget http://pecl.php.net/get/memcached-1.0.0.tgz
tar zxf memcached-1.0.0.tgz
cd memcached-1.0.0
phpize
./configure
make
make install

打开php.ini加上:

extension = "memcached.so"

这样安装就结束了,你可以通过下列命令来确认:

php -m | grep mem

演示Memcached版本的新功能

先虚构一个问题,假设counter初始值是一个整数,不使用increment方法,通过get/set完成每次加一。

在Memcache版本里,我们只能按照大致如下的方式来进行:

$m = new Memcache();
$m->addServer('localhost', 11211);
$v = $m->get('counter');
$m->set('counter', $v + 1);

由于get/set这两个动作无法作为一个原子来操作,所以当多个进程同时处理时,会出现丢失的可能,更让人恼火的是,你根本就不知道什么时候出现丢失。

再看看Memcached版本里,我们是如何做的:

$md = new Memcached();
$md->addServer('localhost', 11211);
$v = $md->get('counter', null, $token)
$md->cas($token, 'counter', $v + 1);

cas是Memcached版本里提供的功能,说白了就是一个乐观锁的功能,如果你把$token的值var_dump出来,就会发现$token其实就是一个版本号,如果通过get得到的$token版本号在cas的时候不对应,就说明已经有别的操作更新了,此时cas操作会失败,至于如何继续操作,就看你自己了。

注:如果你想手动重现一下冲突的情况,可在get和cas之间sleep若干秒,并拷贝两份脚本,先后执行。

顺便说一句,推荐的Memcached版本模块的哈希设置如下:

$md->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$md->setOption(Memcached::OPT_HASH, Memcached::HASH_CRC);

 


两者使用起来几乎一模一样。
复制代码 代码如下:
$mem = new Memcache;
$mem->addServer($memcachehost, '11211');
$mem->addServer($memcachehost, '11212');
$mem->set('hx','9enjoy');
echo $mem->get('hx');

复制代码 代码如下:
$md = new Memcached;
$servers = array(
array($memcachehost, '11211'),
array($memcachehost, '11212')
);
$md->addServers($servers);
$md->set('hx','9enjoy');
echo $md->get('hx');

memcached的方法比memcache多不少,比如getMulti,getByKey,addServers等。
memcached没有memcache的connect方法,目前也还不支持长连接。
memcached 支持 Binary Protocol,而 memcache 不支持,意味着 memcached 会有更高的性能。
Memcache是原生实现的,支持OO和非OO两套接口并存,memcached是使用libmemcached,只支持OO接口。
更详细的区别:http://code.google.com/p/memcached/wiki/PHPClientComparison


memcached服务端是集中式的缓存系统,分布式实现方法是由客户端决定的。
memcached的分布算法一般有两种选择:
1、根据hash(key)的结果,模连接数的余数决定存储到哪个节点,也就是hash(key)% sessions.size(),这个算法简单快速,表现良好。然而这个算法有个缺点,就是在memcached节点增加或者删除的时候,原有的缓存数据将大规模失效,命中率大受影响,如果节点数多,缓存数据多,重建缓存的代价太高,因此有了第二个算法。
2、Consistent Hashing,一致性哈希算法,他的查找节点过程如下:
首先求出memcached服务器(节点)的哈希值,并将其配置到0~232的圆(continuum)上。然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过2的32次方后仍然找不到服务器,就会保存到第一台memcached服务器上。

memcache在没有任何配置的情况下,是使用第一种方法。memcached要实现第一种方法,似乎是使用(未确认):
$md->setOption(Memcached::OPT_HASH, Memcached::HASH_CRC);

第二种一致性哈希算法:

memcache在php.ini中加
复制代码 代码如下:
Memcache.hash_strategy =consistent
Memcache.hash_function =crc32

memcached在程序中加(未确认)
复制代码 代码如下:
$md->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$md->setOption(Memcached::OPT_HASH, Memcached::HASH_CRC);

$mem->setOption(Memcached::OPT_DISTRIBUTION,Memcached::DISTRIBUTION_CONSISTENT);
$mem->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE,true);

一些参考文档:
memcached分布测试报告(一致性哈希情况下的散列函数选择):
http://www.iteye.com/topic/346682
php模块memcache和memcached区别: http://www.111cn.net/article/27366.htm
PHP模块:Memcached > Memcache:http://www.111cn.net/article/27367.htm

20110509@@UPDATE:
如果安装libmemcached有如下出错提示:
make[2]: *** [clients/ms_conn.o] Error 1
make[2]: Leaving directory `/www/soft/libmemcached-0.48'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/www/soft/libmemcached-0.48'
make: *** [all] Error 2

可在configure时增加--disable-64bit CFLAGS="-O3 -march=i686"
即:./configure --prefix=/usr/local/libmemcached --with-memcached --disable-64bit CFLAGS="-O3 -march=i686"


分析

memcache:http://cn2.php.net/manual/en/book.memcache.php
memcached:http://cn2.php.net/manual/en/book.memcached.php
2.Memcache是原生实现的,支持OO和非OO两套接口并存。而memcached是使用libmemcached,只支持OO接口。
3.memcached还有个非常称赞的地方,就是flag不是在操作的时候设置了,而是有了一个统一的setOption()。Memcached实现了更多的memcached协议。
4.memcached支持Binary Protocol,而memcache不支持。这意味着memcached会有更高的性能。不过memcached目前还不支持长连接。

下面有一张表,来对比php客户端扩展memcache与memcached
http://code.google.com/p/memcached/wiki/PHPClientComparison

另外一点也是大家比较关心的,就是所使用的算法。大家都知道“一致性hash算法”是当添加或删除存储节点时,对存储在memcached上的数据影响较小的一种算法。那么在php的两个扩展库中,都可以使用该算法,只是设置方法有所不同。
Memcache
修改php.ini添加:
[Memcache]
Memcache.allow_failover = 1
……
……
Memcache.hash_strategy =consistent
Memcache.hash_function =crc32
……
……
或在php中使用ini_set方法:
Ini_set(‘memcache.hash_strategy','standard');
Ini_set(‘memcache.hash_function','crc32');

Memcached
$mem = new memcached();
$mem->setOption(Memcached::OPT_DISTRIBUTION,Memcached::DISTRIBUTION_CONSISTENT);
$mem->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE,true);

大多数类都有一种称为构造函数的特殊方法。当创建一个对象时,它将自动调用构造函
数,也就是使用new 这个关键字来实例化对象的时候自动调用构造方法。
构造函数的声明与其它操作的声明一样,只是其名称必须是__construct( )。这是PHP5 中
的变化,以前的版本中,构造函数的名称必须与类名相同,这种在PHP5 中仍然可以用,但
现在以经很少有人用了,这样做的好处是可以使构造函数独立于类名,当类名发生改变时不
需要改相应的构造函数名称了。为了向下兼容,如果一个类中没有名为__construct( )的方法,
PHP 将搜索一个php教程4 中的写法,与类名相同名的构造方法。
格式:function __construct ( [参数] ) { ... ... }
在一个类中只能声明一个构造方法,而是只有在每次创建对象的时候都会去调用一次构
造方法,不能主动的调用这个方法,所以通常用它执行一些有用的初始化任务。比如对成属
性在创建对象的时候赋初值。

 

<?php
/*
 * 1.对象中成员的访问(在一个对象的内部方法中,去访问本对轩昂中的其他方法和成员属性)
 * 2.在对象中的方法中都默认有一个$this关键字,这个关键字代表调用这个方法的对象
 *
 * 构造方法
 *
 *   1.是对象创建完成后,“第一个”“自动调用”的方法
 *
 *   2.构造方法的定义,方法名是一个固定的,
 *     在php4中:和类名相同的方法就是构造方法
 *     在php5中:构造方法选择使用 魔术方法__construct() 所有类中声明构造方法都使用这个名称
 *       优点:在改变类名时,构造方法不用改变
 *      魔术方法: 在类中写出了某个魔术方法,这个方法对应的功能就会添加上
 *         方法名称都是固定的(都是系统提供好的),没有自己定义的
 *         每一个魔术方法,都是在不同时刻为了完成某一功能自动调用的方法
 *         不同的魔术方法有不同的调用时机
 *         都是以 __ 开头的方法
 *          __construct(); __destruct(); __set();......
 *    
 *   作用:为成员属性初始化;
 *
 *
 * 析构方法
 *
 *  1.当对象被释放之前最后一个“自动”调用的方法
 *  使用垃圾回收器(java php),而c++手动 的释放
 *
 *  作用:关闭一些资源,作一些清理的工作
 *  
 *  __destruct();
 *
 */
 class Person{
  var $name;
  var $age;
  var $sex;
  
  //php4中的构造方法
  /*function Person()
    {
   //每声明一个对象都会调用
   echo "1111111111111111";
  }*/

  //php5中的构造方法
  function __construct($name,$age,$sex){
   $this->name=$name;
   $this->age=$age;
   $this->sex=$sex;

  }

  function say(){
   //$this->name;//对象中成员的访问使用$this
   echo "我的名字:{$this->name},我的年龄:{$this->age}<br>"
  }

  function run(){

  }

  function eat(){

  }

  //析构方法
  function __destruct(){

  }
 }

$p1=new Person("zhangsan",25,"男");
$p2=new Person;
$p3=new Person;

这是一款关于网站目录备份的php教程网站备份程序了,他可以对你能操作权限的目录进行打包生成rar压缩文件哦,希望有需要的朋友下载看看。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>网站程序备份</title>
</head>
<body>
<form name="myform" method="post" action="">
<?php
error_reporting(E_ALL & ~E_NOTICE);
ini_set('memory_limit', '2048M');
echo "选择要压缩的文件或目录:<br>";
$fdir = opendir('./');
while($file=readdir($fdir))
{
if($file=='.'|| $file=='..')
continue;
echo "<input name='dfile[]' type='checkbox' value='$file' ".($file==basename(__FILE__)?"":"checked")."> ";
if(is_file($file))
{
echo "<font face="wingdings" size="5">2</font> $file<br>";
}
else
{
echo "<font face="wingdings" size="5">0</font> $file<br>";
}
}
?>
<br>
包含下列文件类型:
<input name="file_type" type="text" id="file_type" value="" size="50">
<font color="red">
(文件类型用"|"隔开,默认空则包含任意文件,例:如果需要打包php和jpg文件,则输入"php|jpg")
</font>
<br>
压缩文件保存到目录:
<input name="todir" type="text" id="todir" value="__dwb2011__" size="15">
<font color="red">
(留空为本目录,必须有写入权限)
</font>
<br>
压缩文件名称:
<input name="zipname" type="text" id="zipname" value="dwb2011.zip" size="15">
<font color="red">
(.zip)
</font>
<br>
<br>
<input name="myaction" type="hidden" id="myaction" value="dozip">
<input type='button' value='反选' onclick='selrev();'>
<input type="submit" name="Submit" value=" 开始压缩 ">
<script language='网页特效'>
function selrev()
{
with(document.myform)
{
for(i=0;i<elements.length;i++)
{
thiselm = elements[i];
if(thiselm.name.match(/dfile[]/))
thiselm.checked = !thiselm.checked;
}
}
}
</script>
<?php
error_reporting(E_ALL & ~E_NOTICE);
set_time_limit(0);
class PHPzip
{
var $file_count = 0 ;
var $datastr_len = 0;
var $dirstr_len = 0;
var $filedata = ''; //该变量只被类外部程序访问
var $gzfilename;
var $fp;
var $dirstr='';
var $filefilters = array();
function SetFileFilter($filetype)
{
$this->filefilters = explode('|',$filetype);
}
//返回文件的修改时间格式.
//只为本类内部函数调用.
function unix2DosTime($unixtime = 0)
{
$timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);
if ($timearray['year'] < 1980)
{
$timearray['year'] = 1980;
$timearray['mon'] = 1;
$timearray['mday'] = 1;
$timearray['hours'] = 0;
$timearray['minutes'] = 0;
$timearray['seconds'] = 0;
}
return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
}
//初始化文件,建立文件目录,
//并返回文件的写入权限.
function startfile($path = 'dodo.zip')
{
$this->gzfilename=$path;
$mypathdir=array();
do
{
$mypathdir[] = $path = dirname($path);
} while($path != '.');
@end($mypathdir);
do
{
$path = @current($mypathdir);
@mkdir($path);
} while(@prev($mypathdir));
if($this->fp=@fopen($this->gzfilename,"w"))
{
return true;
}
return false;
}
//添加一个文件到 zip 压缩包中.
function addfile($data, $name)
{
$name = str_replace('', '/', $name);
if(strrchr($name,'/')=='/')
return $this->adddir($name);
if(!empty($this->filefilters))
{
if (!in_array(end(explode(".",$name)), $this->filefilters))
{
return;
}
}
$dtime = dechex($this->unix2DosTime());
$hexdtime = 'x' . $dtime[6] . $dtime[7] . 'x' . $dtime[4] . $dtime[5] . 'x' . $dtime[2] . $dtime[3] . 'x' . $dtime[0] . $dtime[1];
eval('$hexdtime = "' . $hexdtime . '";');
$unc_len = strlen($data);
$crc = crc32($data);
$zdata = gzcompress($data);
$c_len = strlen($zdata);
$zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
//新添文件内容格式化:
$datastr = "x50x4bx03x04";
$datastr .= "x14x00"; // ver needed to extract
$datastr .= "x00x00"; // gen purpose bit flag
$datastr .= "x08x00"; // compression method
$datastr .= $hexdtime; // last mod time and date
$datastr .= pack('V', $crc); // crc32
$datastr .= pack('V', $c_len); // compressed filesize
$datastr .= pack('V', $unc_len); // uncompressed filesize
$datastr .= pack('v', strlen($name)); // length of filename
$datastr .= pack('v', 0); // extra field length
$datastr .= $name;
$datastr .= $zdata;
$datastr .= pack('V', $crc); // crc32
$datastr .= pack('V', $c_len); // compressed filesize
$datastr .= pack('V', $unc_len); // uncompressed filesize
fwrite($this->fp,$datastr); //写入新的文件内容
$my_datastr_len = strlen($datastr);
unset($datastr);
//新添文件目录信息
$dirstr = "x50x4bx01x02";
$dirstr .= "x00x00"; // version made by
$dirstr .= "x14x00"; // version needed to extract
$dirstr .= "x00x00"; // gen purpose bit flag
$dirstr .= "x08x00"; // compression method
$dirstr .= $hexdtime; // last mod time & date
$dirstr .= pack('V', $crc); // crc32
$dirstr .= pack('V', $c_len); // compressed filesize
$dirstr .= pack('V', $unc_len); // uncompressed filesize
$dirstr .= pack('v', strlen($name) ); // length of filename
$dirstr .= pack('v', 0 ); // extra field length
$dirstr .= pack('v', 0 ); // file comment length
$dirstr .= pack('v', 0 ); // disk number start
$dirstr .= pack('v', 0 ); // internal file attributes
$dirstr .= pack('V', 32 ); // external file attributes - 'archive' bit set
$dirstr .= pack('V',$this->datastr_len ); // relative offset of local header
$dirstr .= $name;
$this->dirstr .= $dirstr; //目录信息
$this -> file_count ++;
$this -> dirstr_len += strlen($dirstr);
$this -> datastr_len += $my_datastr_len;
}
function adddir($name)
{
$name = str_replace("", "/", $name);
$datastr = "x50x4bx03x04x0ax00x00x00x00x00x00x00x00x00";
$datastr .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) );
$datastr .= pack("v", 0 ).$name.pack("V", 0).pack("V", 0).pack("V", 0);
fwrite($this->fp,$datastr); //写入新的文件内容
$my_datastr_len = strlen($datastr);
unset($datastr);
$dirstr = "x50x4bx01x02x00x00x0ax00x00x00x00x00x00x00x00x00";
$dirstr .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) );
$dirstr .= pack("v", 0 ).pack("v", 0 ).pack("v", 0 ).pack("v", 0 );
$dirstr .= pack("V", 16 ).pack("V",$this->datastr_len).$name;
$this->dirstr .= $dirstr; //目录信息
$this -> file_count ++;
$this -> dirstr_len += strlen($dirstr);
$this -> datastr_len += $my_datastr_len;
}
function createfile()
{
//压缩包结束信息,包括文件总数,目录信息读取指针位置等信息
$endstr = "x50x4bx05x06x00x00x00x00" .
pack('v', $this -> file_count) .
pack('v', $this -> file_count) .
pack('V', $this -> dirstr_len) .
pack('V', $this -> datastr_len) .
"x00x00";
fwrite($this->fp,$this->dirstr.$endstr);
fclose($this->fp);
}
}
if(!trim($_REQUEST[zipname]))
$_REQUEST[zipname] = "dodozip.zip";
else
$_REQUEST[zipname] = trim($_REQUEST[zipname]);
if(!strrchr(strtolower($_REQUEST[zipname]),'.')=='.zip')
$_REQUEST[zipname] .= ".zip";
$_REQUEST[todir] = str_replace('','/',trim($_REQUEST[todir]));
if(!strrchr(strtolower($_REQUEST[todir]),'/')=='/')
$_REQUEST[todir] .= "/";
if($_REQUEST[todir]=="/")
$_REQUEST[todir] = "./";
function listfiles($dir=".")
{
global $dodozip;
$sub_file_num = 0;
if(is_file("$dir"))
{
if(realpath($dodozip ->gzfilename)!=realpath("$dir"))
{
$dodozip -> addfile(implode('',file("$dir")),"$dir");
return 1;
}
return 0;
}
$handle=opendir("$dir");
while ($file = readdir($handle))
{
if($file=="."||$file=="..")
continue;
if(is_dir("$dir/$file"))
{
$sub_file_num += listfiles("$dir/$file");
}
else
{
if(realpath($dodozip ->gzfilename)!=realpath("$dir/$file"))
{
$dodozip -> addfile(implode('',file("$dir/$file")),"$dir/$file");
$sub_file_num ++;
}
}
}
closedir($handle);
if(!$sub_file_num)
$dodozip -> addfile("","$dir/");
return $sub_file_num;
}
function num_bitunit($num)
{
$bitunit=array(' B',' KB',' MB',' GB');
for($key=0;$key<count($bitunit);$key++)
{
if($num>=pow(2,10*$key)-1)
{ //1023B 会显示为 1KB
$num_bitunit_str=(ceil($num/pow(2,10*$key)*100)/100)." $bitunit[$key]";
}
}
return $num_bitunit_str;
}
if(is_array($_REQUEST[dfile]))
{
$dodozip = new PHPzip;
if($_REQUEST["file_type"] != NULL)
$dodozip -> SetFileFilter($_REQUEST["file_type"]);
if($dodozip -> startfile("$_REQUEST[todir]$_REQUEST[zipname]"))
{
echo "正在添加压缩文件...<br><br>";
$filenum = 0;
foreach($_REQUEST[dfile] as $file)
{
if(is_file($file))
{
if(!empty($dodozip -> filefilters))
if (!in_array(end(explode(".",$file)), $dodozip -> filefilters))
continue;
echo "<font face="wingdings" size="5">2</font> $file<br>";
}
else
{
echo "<font face="wingdings" size="5">0</font> $file<br>";
}
$filenum += listfiles($file);
}
$dodozip -> createfile();
echo "<br>压缩完成,共添加 $filenum 个文件.<br><a href='$_REQUEST[todir]$_REQUEST[zipname]' _fcksavedurl='$_REQUEST[todir]$_REQUEST[zipname]'>$_REQUEST[todir]$_REQUEST[zipname] (".num_bitunit(filesize("$_REQUEST[todir]$_REQUEST[zipname]")).")</a>";
}
else
{
echo "$_REQUEST[todir]$_REQUEST[zipname] 不能写入,请检查路径或权限是否正确.<br>";
}
}
?>
</form>
</body>
</html>

[!--infotagslink--]

相关文章

  • php生成二维码中文乱码问题解决方法

    最近做了个扫描二维码得到vcard的项目,遇到一个问题,有一部分生成完的二维码,用android系统手机扫描后得到的vcard中的中文姓名是乱码,经过比对发现,这部分vcard中ORG这个...2016-11-25
  • c# 三种方法调用WebService接口

    这篇文章主要介绍了c# 三种方法调用WebService接口的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-07
  • C#使用Http Post方式传递Json数据字符串调用Web Service

    这篇文章主要为大家详细介绍了C#使用Http Post方式传递Json数据字符串调用Web Service,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • 运行vbs脚本报错无效字符、中文乱码的解决方法(编码问题)

    今天在写一个vbs的时候,发现中文乱码,后来写好代码正常运行的代码压缩一下给了同事,发现报无效字符,经过验证后发现原来是编码的问题导致,这里就为大家分享一下...2020-06-30
  • 关于Mysql中文乱码问题该如何解决(乱码问题完美解决方案)

    最近两天做项目总是被乱码问题困扰着,这不刚把mysql中文乱码问题解决了,下面小编把我的解决方案分享给大家,供大家参考,也方便以后自己查阅。首先:用show variables like “%colla%”;show varables like “%char%”;这两条...2015-11-24
  • c#动态调用Webservice的两种方法实例

    这篇文章介绍了c#动态调用Webservice的两种方法实例,有需要的朋友可以参考一下...2020-06-25
  • PHP json_encode() 函数详解及中文乱码问题

    在 php 中使用 json_encode() 内置函数(php > 5.2)可以使用得 php 中数据可以与其它语言很好的传递并且使用它。这个函数的功能是将数值转换成json数据存储格式。<&#63;php$arr = array ( 'Name'=>'希亚', 'Age'...2015-11-08
  • c#中WebService的介绍及调用方式小结

    这篇文章主要给大家介绍了关于c#中的WebService及其调用方式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
  • 解决HttpPost+json请求---服务器中文乱码及其他问题

    这篇文章主要介绍了解决HttpPost+json请求---服务器中文乱码及其他问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-22
  • php中iconv编码转换来解决中文乱码的问题

    用到iconv函数把抓取来过的utf-8编码的页面转成gb2312, 发现只有用iconv函数把抓取过来的数据一转码数据就会无缘无故的少一些 代码如下 复制代码 ...2016-11-25
  • DTO 实现 service 和 controller 之间值传递的操作

    这篇文章主要介绍了DTO 实现 service 和 controller 之间值传递的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-22
  • 浅谈PHP调用Webservice思路及源码分享

    方法一:直接调用复制代码 代码如下:<? /******************************************************************************/ /* 文件名 : soapclient.php /* 说 明 : WebService接口客户端例程 /****************...2014-06-07
  • php mail发邮件标题中文乱码的问题解决办法

    本文章来给大家介绍php mail发邮件标题中文乱码的问题解决办法,希望到此类问题的朋友可进入参考。 当使用下面的PHP语句发送电子邮件的时候,如果编码和接收邮箱编码...2016-11-25
  • C# 创建、部署和调用WebService简单示例

    这篇文章主要为大家详细介绍了C# 创建、部署和调用WebService的简单示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • C# Soap调用WebService的实例

    下面小编就为大家带来一篇C# Soap调WebService的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-06-25
  • c#动态改变webservice的url访问地址

    这篇文章主要介绍了c#动态改变webservice的url访问地址,需要的朋友可以参考下...2020-06-25
  • Spring boot 无法注入service问题

    这篇文章主要介绍了Spring boot 无法注入service问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-09
  • WebService 的简单封装接口调用方法

    这篇文章主要介绍了WebService 的简单封装接口调用方法,主要是通过简单的sql语句来查询数据库,从而返回dataset,十分简单实用,有需要的小伙伴可以参考下。...2020-06-25
  • JAVA调用SAP WEBSERVICE服务实现流程图解

    这篇文章主要介绍了JAVA调用SAP WEBSERVICE服务实现流程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-10-11
  • c#编写webservice服务引用实例分享

    c#编写webservice服务引用实例分享,大家参考使用吧...2020-06-25