PHP中data/base64数据流转图片文件输出例子
我们来看看data/base64是什么吧
什么是data:image/*;base64?
答:这是Data URI scheme。
还不懂?
Ps:Data URI scheme是在RFC2397中定义的,目的是将一些小的数据,直接嵌入到网页中,从而不用再从外部文件载入。
例如:
data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAYAAABIdFAMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHhJREFUeNo8zjsOxCAMBFB/ KEAUFFR0Cbng3nQPw68ArZdAlOZppPFIBhH5EAB8b+Tlt9MYQ6i1BuqFaq1CKSVcxZ2Acs6406KUgpt5/ LCKuVgz5BDCSb13ZO99ZOdcZGvt4mJjzMVKqcha68iIePB86GAiOv8CDADlIUQBs7MD3wAAAABJRU5ErkJggg%3D%3D。
将这些字符复制黏贴到火狐的地址栏中并转到,就能看到它了,一张1X36的白灰png图片。
在上面的Data URI中,data表示取得数据的协定名称,image/png 是数据类型名称,base64 是数据的编码方法,逗号后面就是这个image/png文件base64编码后的数据。
目前,Data URI scheme支持的类型有:
data:,文本数据
data:text/plain,文本数据
data:text/html,HTML代码
data:text/html;base64,base64编码的HTML代码
data:text/css,CSS代码
data:text/css;base64,base64编码的CSS代码
data:text/javascript,Javascript代码
data:text/javascript;base64,base64编码的Javascript代码
data:image/gif;base64,base64编码的gif图片数据
data:image/png;base64,base64编码的png图片数据
data:image/jpeg;base64,base64编码的jpeg图片数据
data:image/x-icon;base64,base64编码的icon图片数据
base64简单地说,它把一些 8-bit 数据翻译成标准 ASCII 字符,网上有很多免费的base64 编码和解码的工具,在PHP中可以用函数base64_encode() 进行编码,如
echo base64_encode(file_get_contents('emtalk.png'));
目前,IE8、Firfox、Chrome、Opera浏览器都支持这种小文件嵌入。
写个简单的小函数:
<?php
header('Content-type:text/html;charset=utf-8');
function image_base64($image_file){
if(empty($image_file))return false;
$image_info = getimagesize($image_file);
$base64_image_content = "data:{$image_info['mime']};base64," . chunk_split(base64_encode(file_get_contents($image_file)));
return $base64_image_content;
}
?>
<html>
<head>
<title>逐风博客-图片编码输出测试</title>
</head>
<body>
<img id="img1" width='100' src="<?php echo image_base64('imgtest.jpg');?>"/>
</body>
</html>
并且掌握了PHP生成代码,那么今天逐风君再给小伙伴们带来一个,把data:image/;base64数据流转化回图片文件的处理方法(函数):
/**
* 反编译data/base64数据流并创建图片文件
* @author Lonny ciwdream@gmail.com
* @param string $baseData data/base64数据流
* @param string $Dir 存放图片文件目录
* @param string $fileName 图片文件名称(不含文件后缀)
* @return mixed 返回新创建文件路径或布尔类型
*/
function base64DecImg($baseData, $Dir, $fileName){
// 前台访问URL API
$__URL__= 'http://emtalk.net/';
// 服务器根目录绝对路径获取API
$__root__=isset($_SERVER['DOCUMENT_ROOT'])?$_SERVER['DOCUMENT_ROOT']:(isset($_SERVER['APPL_PHYSICAL_PATH'])?trim($_SERVER['APPL_PHYSICAL_PATH'],"\\"):(isset($_['PATH_TRANSLATED'])?str_replace($_SERVER["PHP_SELF"]):str_replace(str_replace("/","\\",isset($_SERVER["PHP_SELF"])?$_SERVER["PHP_SELF"]:(isset($_SERVER["URL"])?$_SERVER["URL"]:$_SERVER["SCRIPT_NAME"])),"",isset($_SERVER["PATH_TRANSLATED"])?$_SERVER["PATH_TRANSLATED"]:$_SERVER["SCRIPT_FILENAME"])));
// 上诉两个变量,依据实际情况自行修改
try{
$expData = explode(';',$baseData);
$postfix = explode('/',$expData[0]);
if( strstr($postfix[0],'image') ){
$postfix = $postfix[1] == 'jpeg' ? 'jpg' : $postfix[1];
$storageDir = $Dir.DIRECTORY_SEPARATOR.$fileName.'.'.$postfix;
$export = base64_decode(str_replace("{$expData[0]};base64,", '', $baseData));
$returnDir = str_replace(str_replace('/','\\',$__root__),'',$storageDir);
try{
file_put_contents($storageDir, $export);
return $__URL__.$returnDir;
}catch(Exception $e){
return false;
}
}
}catch(Exception $e){
return false;
}
return false;
}
代码看懂没?这只是个简单的小示例,通过代码优化、调整这个函数还可以实现data:image/;base64数据不同数据类型文件的还原呦!
Laravel框架我们用到的不多了,但如果使用需要搭配了,下面我们来看一篇关于搭建php Laravel框架教程详解,具体的操作细节如下所示,希望对各位有帮助。一、安装 Composer
Laravel 框架使用 Composer(PHP包管理工具,参考 Composer 中文文档)来管理代码依赖性。 首先,你需要下载 Composer 的 PHAR 打包文件( composer.phar ),下载完成后把它放在项目目录下或者放到 usr/local/bin 目录下以便在系统中全局调用。在Windows操作系统中,你可以使用 Composer 的Windows安装工具。
二、安装 Laravel
方法一:通过 Laravel 安装器安装
首先,通过 Composer 下载 Laravel 安装器。
composer global require "laravel/installer=~1.1"
请确保把 ~/.composer/vendor/bin 路径添加到 PATH 环境变量里, 这样laravel 可执行文件才能被命令行找到, 以后您就可以在命令行下直接使用 laravel 命令.
安装成功后, 可以使用命令 laravel new 在您指定的目录下创建一份全新安装的 Laravel。例如,laravel new blog 将会在当前目录下创建一个叫 blog 的目录, 此目录里面存放着全新安装的 Laravel 以及其依赖的工具包。这种安装方法比通过 Composer 安装要快许多。
方法二:通过 Composer 的 create-project 命令安装 Laravel
还可以通过在命令行执行 Composer 的 create-project 命令来安装Laravel:
composer create-project laravel/laravel --prefer-dist
方法三:通过下载 Laravel 包安装
Composer 安装完成后,下载最新版Laravel框架,把它解压缩到你服务器上的一个目录中。然后在 Laravel 应用的根目录下运行命令行命令 php composer.phar install (或者 composer install )来安装所有的框架依赖包。在此过程中,为了成功完成安装,你需要在服务器上安装好 Git。
当 Laravel 框架安装好后,你可以使用命令行命令 php composer.phar update 来更新框架。
三、对服务器环境的要求
Laravel 框架对系统环境有如下要求:
PHP >= 5.4
MCrypt PHP 扩展
从 PHP 5.5 版本开始,针对某些操作系统的安装包需要你自己手工安装 PHP 的 JSON 扩展模块。如果你使用的是 Ubuntu,可以通过, apt-get install php5-json 命令直接安装。
四、展示
必要插件安装及配置
我们使用著名的Sentry插件来构建登录等权限验证系统。
打开 ./composer.json ,变更为:
"require": {
"laravel/framework": "4.2.*",
"cartalyst/sentry": "2.1.4"
},
然后,在项目根目录下运行命令
composer update
然后稍等一会儿,它会提示 cartalyst/sentry 2.1.4安装完成。
同理,我们将安装一个开发用的非常强大的插件,way/generators,这是它在composer库中的名字。在 composer.json中增加:
"require-dev": {
"way/generators": "~2.0"
},和“require”同级,放在下面,不是里面哦~。
运行 composer update,之后在 ./app/config/app.php 中 恰当的位置 增加配置:
'Way\Generators\GeneratorsServiceProvider'安装完成过,在命令行中运行 php artisan,就可以看到这个插件带来的许多新的功能。
有人会问,为什么用了国内镜像还是如此之慢?其实composer在update的时候最慢的地方并不是下载,而是下载之前的依赖关系解析,由于Laravel依赖的composer包非常之多,PHP脚本的执行速度又比较慢,所以每次update等个两三分钟很正常,习惯就好。
3. 数据库建立及迁移
数据库配置文件位于 ./app/config/database.php,我们需要把“connections”中的“mysql”项改成我们需要的配置。下面是我的配置:
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'laravel',
'username' => 'root',
'password' => 'password',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => 'l4_',
),
prefix为表前缀,这个Laravel会帮我们自动维护,大胆写上不用担心。
这时候你需要去数据库建立此数据库,然后在命令行中输入:
php artisan migrate --package=cartalyst/sentry
执行完成后,你的数据库里就有了5张表,这是sentry自己建立的。sentry在Laravel4下的配置详情见 https://cartalyst.com/manual/sentry#laravel-4,我大致说一下:
在 ./app/config/app.php 中 相应的位置 分别增加以下两行:
'Cartalyst\Sentry\SentryServiceProvider','Sentry' => 'Cartalyst\Sentry\Facades\Laravel\Sentry',权限系统的数据库配置到此为止。
我们的简单blog系统将会有两种元素,Article和Page,下面我们将创建articles和pages数据表,命令行运行:
php artisan migrate:make create_articles_table --create=articles
php artisan migrate:make create_pages_table --create=pages
这时候,去到 ./app/database/migrations,将会看到多出了两个文件,这就是数据库迁移文件,过一会我们将操作artisan将这两个文件描述的两张表变成数据库中真实的两张表,放心,一切都是自动的。
下面,在***_create_articles_table.php中修改:
Schema::create('articles', function(Blueprint $table)
{
$table->increments('id');
$table->string('title');
$table->string('slug')->nullable();
$table->text('body')->nullable();
$table->string('image')->nullable();
$table->integer('user_id');
$table->timestamps();
});
在***_create_pages_table.php中修改:
Schema::create('pages', function(Blueprint $table)
{
$table->increments('id');
$table->string('title');
$table->string('slug')->nullable();
$table->text('body')->nullable();
$table->integer('user_id');
$table->timestamps();
});
下面,就是见证奇迹的时刻,在命令行中运行:
php artisan migrate
这时候数据库中的articles表和pages表就建立完成了。
4. 模型 Models
接下来我们将接触Laravel最为强大的部分,Eloquent ORM,真正提高生产力的地方,借用库克的话说一句,鹅妹子英!
我们在命令行运行下列语句以创建两个model:
php artisan generate:model article
php artisan generate:model page这时候,在 app/models/ 下就出现了两个文件 Article.php 和 Page.php,这是两个 Model 类,他们都继承了Laravel提供的核心类 \Eloquent。这里需要强调一下,用命令行的方式创建文件,和自己手动创建文件没有任何区别,你也可以尝试自己创建这两个 Model 类哦。
Model 即为 MVC 中的 M,翻译为 模型,负责跟数据库交互。在 Eloquent 中,数据库中每一张表对应着一个 Model 类。
如果你从其他框架转过来,可能对这里一笔带过的 Model 部分很不适应,没办法,是因为 Eloquent 实在太强大了啦,真的没什么好做的,继承一下 Eloquent 类就能实现很多很多功能了。详见 Eloquent 系列教程:深入理解 Laravel Eloquent(一)——基本概念及用法
5. 数据库填充
分别运行下列命令:
php artisan generate:seed page
php artisan generate:seed article这时,在 ./app/database/seeds/ 下就出现了两个新的文件,这就是我们的数据库填充文件。Laravel提供自动数据库填充,十分方便。
generator默认使用Faker\Factory作为随机数据生成器,所以我们需要安装这个composer包,地址是 https://packagist.org/packages/fzaninotto/faker ,跟generator一起安装在 require-dev 中即可。具体安装请自行完成,可以参考Sentry和Generator,这是第一次练习。
接下来,分别更改这两个文件:
Article::create([
'title' => $faker->sentence($nbWords = 6),
'slug' => 'first-post',
'body' => $faker->paragraph($nbSentences = 5),
'user_id' => 1,
]);Page::create([
'title' => $faker->sentence($nbWords = 6),
'slug' => 'first-page',
'body' => $faker->paragraph($nbSentences = 5),
'user_id' => 1,
]);
然后,我们需要在 DatabaseSeeder.php 中增加两行,让Laravel在seed的时候会带上我们新增的这两个seed文件。
$this->call('ArticleTableSeeder');
$this->call('PageTableSeeder');
下面就要真正的把数据填充进数据库了:
php artisan db:seed操作完成以后去数据库看看,数据已经填充进去了,article和page各10行。
一、db sql语句
//db used for php无限分类
create table tree(
id int(10) not null primary key auto_increment,
name varchar(255) not null,
lft int(10) not null default 0,
rgt int(10) not null default 0,
status int(1) not null default 0,
index lft (`lft`),
index rgt (`rgt`),
index status(`status`)
)charset utf8;
insert into tree value (null,'Food',1,18,0);
insert into tree value (null,'Fruit',2,11,0);
insert into tree value (null,'Red',3,6,0);
insert into tree value (null,'Cherry',4,5,0);
insert into tree value (null,'Yellow',7,10,0);
insert into tree value (null,'Banana',8,9,0);
insert into tree value (null,'Meat',12,17,0);
insert into tree value (null,'Beef',13,14,0);
insert into tree value (null,'Pork',15,16,0);
二、php文件
<?php
error_reporting(0);
/*
1 Food 18
+------------------------------+
2 Fruit 11 12 Meat 17
+-------------+ +------------+
3 Red 6 7 Yellow 10 13 Beef 14 15 Pork 16
4 Cherry 5 8 Banana 9
descendants = (right – left - 1) / 2
*/
/**
*用于移动一个节点(包括子节点)
*@param array $pdata = array('id'=>主键,'root'=>名称) 二选一 父节点(为空时插入最大的父节点)
*@param array $ndata = array('id'=>主键,'root'=>名称) 二选一 下一个兄弟节点(没有兄弟的时候就不用)
*@param array $cdata = array('id'=>主键,'root'=>名称) 二选一 当前待移动的节点
*/
function move_tree_all($pdata=array(),$ndata=array(),$cdata=array()) {
$cid = $cdata['id'] ? intval($cdata['id']) : '';
$croot = $cdata['root'];
if(!$cid && !$croot) return;
//需自加判断
//1、cdata不能为顶级
//2、cdata不能比$pdata等级高
$adata = get_tree_all($cdata); //获取当前移动节点的所有节点
delete_tree_all($cdata,1); //逻辑删除当前移动节点的所有节点
foreach($adata as $k => $val) {
if($k != 0) {
$pdata = array('root'=>$val['parent']);
insert_tree($pdata,'',$val['name'],1);
} else { //first
insert_tree($pdata,$ndata,$val['name'],1);
}
}
}
/**
*用于移动一个节点(不包括子节点)
*@param array $pdata = array('id'=>主键,'root'=>名称) 二选一 父节点(为空时插入最大的父节点)
*@param array $ndata = array('id'=>主键,'root'=>名称) 二选一 下一个兄弟节点(没有兄弟的时候就不用)
*@param array $cdata = array('id'=>主键,'root'=>名称) 二选一 当前待移动的节点
*/
function move_tree_item($pdata=array(),$ndata=array(),$cdata=array()) {
$cid = $cdata['id'] ? intval($cdata['id']) : '';
$croot = $cdata['root'];
if(!$cid && !$croot) return;
//需自加判断
//1、cdata不能为顶级
if(!$croot) {
$sql = "SELECT name from tree where id = $cid";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
$croot = $row['name'];
unset($sql);
}
delete_tree_item($cdata,1);
insert_tree($pdata,$ndata,$croot,1);
}
/**
*用于插入一个节点
*@param array $pdata = array('id'=>主键,'root'=>名称) 二选一 父节点(为空时插入最大的父节点)
*@param array $ndata = array('id'=>主键,'root'=>名称) 二选一 下一个兄弟节点(没有兄弟的时候就不用)
*@param string $name string 新插入的名称
*@param int $update 默认为空,为1时更新插入
*/
function insert_tree($pdata=array(),$ndata=array(),$name,$update='') {
if(!$name) return;
$pid = $pdata['id'] ? intval($pdata['id']) : '';
$proot = $pdata['root'];
$nid = $ndata['id'] ? intval($ndata['id']) : '';
$nroot = $ndata['root'];
//有父无兄(最小的子节点,父节点的最后一个儿子)
if(($pid || $proot) && !($nid || $nroot)) {
$sql = $pid ? "SELECT lft, rgt FROM tree WHERE id = '{$pid}';" : "SELECT lft, rgt FROM tree WHERE name = '{$proot}';";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
unset($sql);
//新节点
$lft = $row['rgt'];
$rgt = $lft+1;
if(!$update) {
$sql = "insert into tree values (null,'{$name}',$lft,$rgt,0);";
$sql1 = "update tree set rgt = rgt+2 where rgt >= {$row['rgt']}";
$sql2 = "update tree set lft = lft+2 where lft >= {$row['rgt']}";
} else {
$sql = "update tree set lft=$lft,rgt=$rgt,status=0 where name ='{$name}';";
$sql1 = "update tree set rgt = rgt+2 where status =0 and rgt >= {$row['rgt']}";
$sql2 = "update tree set lft = lft+2 where status =0 and lft >= {$row['rgt']}";
}
mysql_query($sql1);
mysql_query($sql2);
mysql_query($sql); //last add new data
}
//有父有兄
if(($pid || $proot) && ($nid || $nroot)) {
$sql = $nid ? "SELECT lft, rgt FROM tree WHERE id = '{$nid}';" : "SELECT lft, rgt FROM tree WHERE name = '{$nroot}';";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
unset($sql);
//新节点
$lft = $row['lft'];
$rgt = $lft+1;
if(!$update) {
$sql = "insert into tree values (null,'{$name}',$lft,$rgt,0);";
$sql1 = "update tree set rgt = rgt+2 where rgt >= {$row['lft']};";
$sql2 = "update tree set lft = lft+2 where lft >= {$row['lft']};";
} else {
$sql = "update tree set lft=$lft,rgt=$rgt,status=0 where name ='{$name}';";
$sql1 = "update tree set rgt = rgt+2 where status = 0 and rgt >= {$row['lft']};";
$sql2 = "update tree set lft = lft+2 where status = 0 and lft >= {$row['lft']};";
}
mysql_query($sql1);
mysql_query($sql2);
mysql_query($sql); //last add new data
}
//无父无兄(大佬)
if(!($pid || $proot) && !($nid || $nroot)) {
$sql = "SELECT max(`rgt`) as rgt FROM tree;";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
unset($sql);
//新节点
$lft = 1;
$rgt = $row['rgt']+2;
if(!$update) {
$sql = "insert into tree values (null,'{$name}',$lft,$rgt,0);";
$sql1 = "update tree set rgt = rgt+1";
$sql2 = "update tree set lft = lft+1";
} else {
$sql = "update tree set lft=$lft,rgt=$rgt,status=0 where name ='{$name}';";
$sql1 = "update tree set rgt = rgt+1 where status = 0";
$sql2 = "update tree set lft = lft+1 where status = 0";
}
mysql_query($sql1);
mysql_query($sql2);
mysql_query($sql); //last add new data
}
}
/**
*用于删除一个节点(包括子节点)
*@param array $data = array('id'=>主键,'root'=>名称) 二选一
*@param int $update 默认为空,为1时逻辑删除
*/
function delete_tree_all($data,$update='') {
$id = $data['id'] ? intval($data['id']) : '';
$root = $data['root'];
if(!$id && !$root) return;
$sql = $id ? "SELECT lft, rgt FROM tree WHERE id = '{$id}';" : "SELECT lft, rgt FROM tree WHERE name = '{$root}';";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
unset($sql);
$middle = $row['rgt']-$row['lft']+1;
if(!$update) {
$sql = "delete from tree where lft BETWEEN '" . $row['lft'] . "' AND '" . $row['rgt'] ."'";
$sql1 = "update tree set rgt = rgt-{$middle} where rgt > {$row['rgt']}";
$sql2 = "update tree set lft = lft-{$middle} where lft > {$row['rgt']}";
} else {
$sql = "update tree set status = 1 where lft BETWEEN '" . $row['lft'] . "' AND '" . $row['rgt'] ."'";
$sql1 = "update tree set rgt = rgt-{$middle} where status=0 and rgt > {$row['rgt']}";
$sql2 = "update tree set lft = lft-{$middle} where status=0 and lft > {$row['rgt']}";
}
mysql_query($sql);
mysql_query($sql1);
mysql_query($sql2);
}
/**
*用于删除一个节点(不包括子节点)
*@param array $data = array('id'=>主键,'root'=>名称) 二选一
*@param int $update 默认为空,为1时逻辑删除
*/
function delete_tree_item($data,$update='') {
$id = $data['id'] ? intval($data['id']) : '';
$root = $data['root'];
if(!$id && !$root) return;
$sql = $id ? "SELECT id,lft, rgt FROM tree WHERE id = '{$id}';" : "SELECT id,lft, rgt FROM tree WHERE name = '{$root}';";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
unset($sql);
if(!$update) {
$sql = "delete from tree where id = {$row['id']};";
$sql1 = "update tree set rgt = rgt-1,lft = lft -1 where lft > {$row['lft']} and rgt < {$row['rgt']}";
$sql2 = "update tree set lft = lft-2 where lft > {$row['rgt']}";
$sql3 = "update tree set rgt = rgt-2 where rgt > {$row['rgt']}";
} else {
$sql = "update tree set status = 1 where id = {$row['id']};";
$sql1 = "update tree set rgt = rgt-1,lft = lft -1 where status = 0 and lft > {$row['lft']} and rgt < {$row['rgt']}";
$sql2 = "update tree set lft = lft-2 where status = 0 and lft > {$row['rgt']}";
$sql3 = "update tree set rgt = rgt-2 where status = 0 and rgt > {$row['rgt']}";
}
mysql_query($sql);
mysql_query($sql1);
//can do or not do just right,but not do load empty 2 number in middle
mysql_query($sql2);
mysql_query($sql3);
}
/**
*用于获取所有的节点
*@param array $data = array('id'=>主键,'root'=>名称) 二选一
*/
function get_tree_all($data) {
$id = $data['id'] ? intval($data['id']) : '';
$root = $data['root'];
if(!$id && !$root) return;
$sql = $id ? "SELECT lft, rgt FROM tree WHERE id = '{$id}';" : "SELECT lft, rgt FROM tree WHERE name = '{$root}';";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
$adata = array(); //所有数据
$right = array(); //计数
$prev = array();
$result = mysql_query("SELECT id,name, lft, rgt FROM tree WHERE lft BETWEEN '" . $row['lft'] . "' AND '" . $row['rgt'] ."' ORDER BY lft ASC ;");
while ($row = mysql_fetch_assoc($result)) {
if (count($right) > 0) {
while ($right[count($right) - 1] < $row['rgt']) { // 检查我们是否应该将节点移出堆栈
array_pop($right);
array_pop($prev);
}
}
$parent = $prev ? end($prev) : '';
$adata[] = array('id'=>$row['id'],'name'=>$row['name'],'level'=>count($right),'parent'=>$parent);
$right[] = $row['rgt'];
$prev[] = $row['name'];
}
return $adata;
}
/**
*用于展示分类
*@param array $data = array('id'=>主键,'root'=>名称) 二选一
*/
function display_tree($data) {
$id = $data['id'] ? intval($data['id']) : '';
$root = $data['root'];
if(!$id && !$root) return;
$sql = $id ? "SELECT lft, rgt FROM tree WHERE id = '{$id}';" : "SELECT lft, rgt FROM tree WHERE name = '{$root}';";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
$right = array();
$result = mysql_query("SELECT name, lft, rgt FROM tree WHERE lft BETWEEN '" . $row['lft'] . "' AND '" . $row['rgt'] ."' ORDER BY lft ASC ;");
while ($row = mysql_fetch_assoc($result)) {
if (count($right) > 0) { // 检查我们是否应该将节点移出堆栈
while ($right[count($right) - 1] < $row['rgt']) {
array_pop($right);
}
}
echo str_repeat(' ',count($right)) . $row['name'] . "\n";
$right[] = $row['rgt'];
}
}
mysql_connect('localhost','root','') or die('connect error');
mysql_select_db('test') or die('database error');
mysql_query('set names utf8');
display_tree(array('root'=>'Food'));
//display_tree(array('root'=>'bigboss'));
//move_tree_all($pdata=array('root'=>'Fruit'),$ndata=array('root'=>'Red'),$cdata=array('root'=>'Meat'));
//move_tree_all('','',$cdata=array('root'=>'Meat'));
//move_tree_item('','',array('root'=>'Red'));
//move_tree_item(array('root'=>'Red'),array('root'=>'Cherry'),array('root'=>'Fruit'));
//delete_tree_all(array('root'=>'Yellow'));
//delete_tree_all(array('root'=>'Meat'));
//delete_tree_item(array('root'=>'Meat'));
//insert_tree('','','bigboss');
//insert_tree(array('root'=>'Red'),'','dalao');
//insert_tree(array('root'=>'Red'),array('root'=>'Cherry'),'baddalao');
//insert_tree(array('root'=>'Fruit'),array('root'=>'Red'),'Redbother');
display_tree(array('root'=>'Food'));
微信红包api接口实现小编以前有介绍过相关的教程,不过这次好像有一点不一样下面我们来看看,教程比上次的更完整。一、微信红包文档说明
目前微信红包总共分现金红包和裂变红包两种。
1、现金红包:https://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5
2、裂变红包:https://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=16_5
更多请查看:https://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php
二、php接口实现
本文讲解现金红包的调用,其他的大体一样,就不去尝试了。
参数说明:
代码实现:
片段一、
/**
* 微信支付
* @param string $openid 用户openid
*/
public function pay($re_openid)
{
include_once('WxPacketClass.php');
$wxHongBaoHelper = new WxPacketClass($this->app_sign);
$wxHongBaoHelper->setParameter("nonce_str", $this->great_rand());//随机字符串,丌长于 32 位
$wxHongBaoHelper->setParameter("mch_billno", $this->app_mchid.date('YmdHis').rand(1000, 9999));//订单号(28位)
$wxHongBaoHelper->setParameter("mch_id", $this->app_mchid);//商户号
$wxHongBaoHelper->setParameter("wxappid", $this->app_id);
$wxHongBaoHelper->setParameter("send_name", '扬和宏科技');//红包发送者名称
$wxHongBaoHelper->setParameter("re_openid", $re_openid);//openid
$wxHongBaoHelper->setParameter("total_amount", 100);//付款金额,单位分
$wxHongBaoHelper->setParameter("total_num", 1);//红包?Х抛苋耸?br />
$wxHongBaoHelper->setParameter("wishing", '给您拜个晚年,祝您晚年幸福!');//红包祝福诧
$wxHongBaoHelper->setParameter("client_ip", '127.0.0.1');//调用接口的机器 Ip 地址
$wxHongBaoHelper->setParameter("act_name", '拜年红包活动');//活劢名称
$wxHongBaoHelper->setParameter("remark", '大家快来抢!');//备注信息
$postXml = $wxHongBaoHelper->create_hongbao_xml();
$url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';
$responseXml = $wxHongBaoHelper->curl_post_ssl($url, $postXml);
$responseObj = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);
return $responseObj->return_code;
}
片段二、
//生成红包接口XML信息
/*
<xml>
<sign>![CDATA[E1EE61A9]]</sign>
<mch_billno>![CDATA[00100]]</mch_billno>
<mch_id>![CDATA[888]]</mch_id>
<wxappid>![CDATA[wxcbda96de0b165486]]</wxappid>
<send_name>![CDATA[send_name]]</send_name>
<re_openid>![CDATA[onqOjjXXXXXXXXX]]</re_openid>
<total_amount>![CDATA[100]]</total_amount>
<total_num>![CDATA[1]]</total_num>
<wishing>![CDATA[恭喜发财]]</wishing>
<client_ip>![CDATA[127.0.0.1]]</client_ip>
<act_name>![CDATA[新年红包]]</act_name>
<act_id>![CDATA[act_id]]</act_id>
<remark>![CDATA[新年红包]]</remark>
</xml>
*/
function create_hongbao_xml($retcode = 0, $reterrmsg = "ok"){
try {
$this->setParameter('sign', $this->get_sign());
$commonUtil = new CommonUtil();
return $commonUtil->arrayToXml($this->parameters);
}catch (SDKException $e) {
die($e->errorMessage());
}
}
片段三、
function curl_post_ssl($url, $vars, $second=30,$aHeader=array()) {
$ch = curl_init();
//超时时间
curl_setopt($ch,CURLOPT_TIMEOUT,$second);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
//这里设置代理,如果有的话
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
//cert 与 key 分别属于两个.pem文件
curl_setopt($ch,CURLOPT_SSLCERT,dirname(__FILE__).DIRECTORY_SEPARATOR.'cert'.DIRECTORY_SEPARATOR.'apiclient_cert.pem');
curl_setopt($ch,CURLOPT_SSLKEY,dirname(__FILE__).DIRECTORY_SEPARATOR.'cert'.DIRECTORY_SEPARATOR.'apiclient_key.pem');
curl_setopt($ch,CURLOPT_CAINFO,dirname(__FILE__).DIRECTORY_SEPARATOR.'cert'.DIRECTORY_SEPARATOR.'rootca.pem');
if( count($aHeader) >= 1 ) curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$vars);
$data = curl_exec($ch);
if($data){
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
return false;
}
}
代码结构:
|~action/
| `-PacketClass.php
|~lib/
| |~cert/
| | |-apiclient_cert.pem
| | |-apiclient_key.pem
| | `-rootca.pem
| |-SdkExtraClass.php
| |-WxApi.php
| `-WxPacketClass.php
`-index.php
每个文件都有详细的说明。
三、效果展示
相关文章
- 下面小编来给大家演示几个php操作zip文件的实例,我们可以读取zip包中指定文件与删除zip包中指定文件,下面来给大这介绍一下。 从zip压缩文件中提取文件 代...2016-11-25
使用PHP+JavaScript将HTML页面转换为图片的实例分享
这篇文章主要介绍了使用PHP+JavaScript将HTML元素转换为图片的实例分享,文后结果的截图只能体现出替换的字体,也不能说将静态页面转为图片可以加快加载,只是这种做法比较interesting XD需要的朋友可以参考下...2016-04-19Jupyter Notebook读取csv文件出现的问题及解决
这篇文章主要介绍了JupyterNotebook读取csv文件出现的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2023-01-06- 这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
- 今天小编在这里就来给各位Photoshop的这一款软件的使用者们来说说把古装美女图片转为细腻的工笔画效果的制作教程,各位想知道方法的使用者们,那么下面就快来跟着小编一...2016-09-14
- 这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
- php如何实现抓取网页图片,相较于手动的粘贴复制,使用小程序要方便快捷多了,喜欢编程的人总会喜欢制作一些简单有用的小软件,最近就参考了网上一个php抓取图片代码,封装了一个php远程抓取图片的类,测试了一下,效果还不错分享...2015-10-30
- 有时我们接受或下载到的PSD文件打开是空白的,那么我们要如何来解决这个 问题了,下面一聚教程小伙伴就为各位介绍Photoshop打开PSD文件空白解决办法。 1、如我们打开...2016-09-14
- C#使用System.IO中的文件操作方法在Windows系统中处理本地文件相当顺手,这里我们还总结了在Oracle中保存文件的方法,嗯,接下来就来看看整理的C#操作本地文件及保存文件到数据库的基本方法总结...2020-06-25
- 这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
- 这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下...2020-06-25
jquery左右滚动焦点图banner图片鼠标经过显示上下页按钮
jquery左右滚动焦点图banner图片鼠标经过显示上下页按钮...2013-10-13- 这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
- 下面小编就为大家带来一篇利用JS实现点击按钮后图片自动切换的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-25
php无刷新利用iframe实现页面无刷新上传文件(1/2)
利用form表单的target属性和iframe 一、上传文件的一个php教程方法。 该方法接受一个$file参数,该参数为从客户端获取的$_files变量,返回重新命名后的文件名,如果上传失...2016-11-25- Photoshop的这一款软件小编相信很多的人都已经是使用过了吧,那么今天小编在这里就给大家带来了用Photoshop软件制作枪战电影海报的教程,想知道制作步骤的玩家们,那么下面...2016-09-14
- 要替换字符串中的内容我们只要利用php相关函数,如strstr,str_replace,正则表达式了,那么我们要替换目录所有文件的内容就需要先遍历目录再打开文件再利用上面讲的函数替...2016-11-25
- 又码了一个周末的代码,这次在做一些关于文件上传的东西。(PHP UPLOAD)小有收获项目是一个BT种子列表,用户有权限上传自己的种子,然后配合BT TRACK服务器把种子的信息写出来...2016-11-25
- 这篇文章主要为大家详细介绍了js实现上传图片及时预览的相关资料,具有一定的参考价值,感兴趣的朋友可以参考一下...2016-05-09
- 今天小编在这里就来给photoshop的这一款软件的使用者们来说下AI源文件转photoshop图像变模糊问题的解决教程,各位想知道具体解决方法的使用者们,那么下面就快来跟着小编...2016-09-14