PHP技巧-支付宝公钥自动整理工具开发思路和完整代码

写了上一篇文章之后,心血来潮想写个页面,做个便民工具什么的。就算声明不会存储他人密钥,可是万一别人还是不放心呢?赖上我怎么办?授人以鱼不如授人以渔嘛,本站的核心就是这个啊。所以~~~

截取函数

首先,要把这个东西整理出来,我们要让这个支付宝公钥变成四个部分,也就是三行64,一行24。第一个想到的方法是跑循环,可是我觉得没必要吧,一来我没想到什么函数适合,二来我其实心底里有个很熟悉的函数,那就是“mb_substr”这个啦。以前改过不少模板的时候,经常会用这个函数的。

官方文档:http://php.net/manual/zh/function.mb-substr.php

先来介绍下,mb_substr这个函数有四个参数:

参数 作用
str 必填,要截取的字符串变量
start 必填,开始的位置,指针第一个是0
length 可选,截取的数量,从开始位置计算,如果没这个参数则取到结尾
encoding 可选,编码格式,如果没指定则使用内部字符编码

用法示例

首先把密钥赋值给一个变量,然后用这个函数来截取字符串,再赋值变量,然后输出。

代码如下:

  1. //把密钥赋值给 $key 
  2. $key = ‘MIGfMA0G*******DAQAB’;
  3. //用mb_substr处理
  4. //把$key从第一个开始,也就是指针0,截取64个,编码UTF8
  5. $key1 = mb_substr( $key, 0, 64, ‘utf-8’);
  6. //输出变量的值
  7. echo $key1;

注意一点是,指针从0开始,所以0就是第一个,那么,64就是第65个。所以第二行的话应该这么写:

  1. //错误写法
  2. $key2 = mb_substr( $key, 65, 64, ‘utf-8’);
  3. //正确写法
  4. $key2 = mb_substr( $key, 64, 64, ‘utf-8’);

由于密钥都是字母数字和特定符号,不会出现中文或特殊符号,所以其实编码是可以不声明的,不过为了以防万一可以全局声明下,这样就不用写太多无用的定义了。代码有时候需要简洁点好。最后一个只剩下24,所以也可以不用声明了。

  1. //声明编码
  2. header(“Content-type: text/html; charset=utf-8”);
  3. //截取最后一段
  4. $key4 = mb_substr($key, 192);
  5. //或者
  6. $key4 = mb_substr($key, 192, 24);

完整代码

下面是完整代码,复制代码到记事本,替换$key里面的值,改为你的密钥,然后重命名为key.php。把文件放在PHP主机环境下运行打开即可得到转换后的内容,然后直接复制内容做成支付宝公钥。

  1. <?php
  2. header(“Content-type: text/html; charset=utf-8”);
  3. //替换括号里的内容。
  4. $key = ‘MIGfMA0G*******DAQAB’;
  5. $key1 = mb_substr($key, 0, 64);
  6. $key2 = mb_substr($key, 64, 64);
  7. $key3 = mb_substr($key, 128, 64);
  8. $key4 = mb_substr($key, 192);
  9. echo “—–BEGIN PUBLIC KEY—–<br>”;
  10. echo $key1.“<br>”;
  11. echo $key2.“<br>”;
  12. echo $key3.“<br>”;
  13. echo $key4.“<br>”;
  14. echo “—–END PUBLIC KEY—–<br>”;
  15. ?>

扩展阅读

1,由于证书格式规定,所以加了第12行和17行;

2,PHP中,多个变量或字符串之间,用“.”连接起来;

3:如果第三个参数没设定,第四个请勿设定,否则报错;

4:这个函数如果未开启,请在php.ini里修改开启。

开启方法,搜索“php_mbstring”,把;extension前面的分号去掉。然后重启环境。

5:如果想验证长度,可以利用另一个函数“strlen”。

  1. echo strlen(trim($key1)).’–‘;
  2. echo strlen(trim($key2)).’–‘;
  3. echo strlen(trim($key3)).’–‘;
  4. echo strlen(trim($key4));

实际如出如图

PHP DEBUG技巧-Division by zero报错处理

这几天有个opencart客户买了个模板,由于是新手要我帮忙装和调试,一开始说有个什么错误,可是我去看没发现。我是中文看的,英文下才有报错。

由于是付费买正版,发现问题也着急,应该是找作者解决的,找半天没找到作者联系方式。由于也是老客户了,反正也不会是大问题,还是我自己看看吧。下面进入正题,不BB了。

错误提示

在打开某些产品分类或者某些产品页面的时候,特定语言才报错。

错误是:Division by zero in 巴拉巴拉

错误原因

这个错误的原因,就是运算的过程中,被除数是0。上过小学的都知道“0是不可以作为被除数的”。

解决思路

1:判断值为0的时候跳过运算;

2:如果非要赋值给一个变量,可以做判断后赋固定值或者输出false,后面代码判断如果变量是true才使用它进行下一步代码的实现。

DEBUGING

解决问题之前,先来个两个小知识点:

1、在opencart中,vqmod的优先等级是最高的

2、哪里报错不一定错误就在哪里,但是首先看的还是报错的地方。

从上图中,我们找到了vqcache下对应的文件对应行数,发现如下代码:

  1. // Cosyone custom code starts   
  2. if ((float)$result[‘special’]) {
  3.     $sales_percantage = ((($this->tax->calculate($result[‘price’], $result[‘tax_class_id’], $this->config->get(‘config_tax’)))-($this->tax->calculate($result[‘special’], $result[‘tax_class_id’], $this->config->get(‘config_tax’))))/(($this->tax->calculate($result[‘price’], $result[‘tax_class_id’], $this->config->get(‘config_tax’)))/100));
  4. else {
  5.     $sales_percantage = false;
  6. }

从这个代码可以看出有若干个参数,我们留意“/”后面的被除数就好,这里被除数有两个地方,其中第二个是正整数100,可以排除。那么问题就在下面这段代码中:

  1. $this->tax->calculate($result[‘price’], $result[‘tax_class_id’], $this->config->get(‘config_tax’))

我们从上面这个方法里看到三个参数,分别用print_r打印了下参数的值,结果发现第二个参数“$result[‘tax_class_id’]”是“000000”。很显然,如果这个是0,我们就要让:

$sales_percantage  = false ;

所以我们这里的代码要修改为:

  1. // Cosyone custom code starts   
  2. if ((float)$result[‘special’] && $result[‘tax_class_id’]) {
  3.     $sales_percantage = ((($this->tax->calculate($result[‘price’], $result[‘tax_class_id’], $this->config->get(‘config_tax’)))-($this->tax->calculate($result[‘special’], $result[‘tax_class_id’], $this->config->get(‘config_tax’))))/(($this->tax->calculate($result[‘price’], $result[‘tax_class_id’], $this->config->get(‘config_tax’)))/100));
  4. else {
  5.     $sales_percantage = false;
  6. }

也就是,加多一个判断依据,必须满足两个值都存在的前提下,才进行如下运算,否则是false。

修改代码,保存代码,上传文件,刷新页面,警告提示语消失,over。

但是,毕竟我们改的是缓存文件,真正要修改好代码,我们还是要把代码写到核心文件或者插件的文件里。

修改源

首先,我们从三个地方查找,分别是:

核心文件:/catalog/controller/product/category.php;

vqmod:/vqmod/xml/*.xml;

ocmod:上传插件的ocmod.xml文件备份,或者数据库查看:oc_modification表xml字段;

虽然vqmod的优先等级高于ocmod,但是其实先从比较方便的地方找起也是可以的。有个方法可以排除是否ocmod。如果是ocmod插件的,缓存文件名必定有“system_storage_modification”。

但是也由于vqmod优先等级最高,所以被ocmod缓存的文件的文件名也可能有这个字样,所以排查的顺序如上所述。【如果报错指向“/system/storage/modification/”则一定是ocmod插件引起】

核心文件的话,编辑器打开ctrl+F进行关键字查找修改。

如果是vqmod的xml,要么排除法排除不可能是的文件,然后从可能是的文件里查找。如果文件太多就用notepad++等编辑器或者IDE工具,可以进行目录搜索,从中找到文件。

如果是ocmod,则用MYSQL工具进行字段like %…% 搜索,或者用SQL语句:

  1. SELECT * FROM `oc_modification` WHERE `xml` like “%关键代码%”

由于这里存的数据被转义过,所以搜索的内容不要带有换行之类的,抓取比较有特点的代码进行查找和修改。修改的时候注意转义的影响哈。当然现在很多MYSQL管理工具这一点做的还是挺好的。建议最好修改插件的ocmod.xml文件,然后重新上传一次。平时插件装了后自己留备份还是有必要的。如果没文件就导出备份再修改。

扩展

上面的示例代码刚好是刚遇到的,所以拿来举例子。授人以鱼不如授人以渔,有的小问题大家花钱又心疼,想自己折腾也未尝不可以,以后还是会提供更多这类比较初级的解决方案给大家。下面另外举例子:

  1. $a = 0;
  2. $value = $key / $a;
  3. //这样可能会提示警告语
  4. if ($a) {
  5.     $value = $key / $a;
  6. }else{
  7.     $value = false;
  8. }
  9. //对$value进行赋值计算结果或者false,也可以赋值预设数字,以便后面进行引用。

上面的方法只是一些示例和排错的技巧,一种思路,具体情况具体分析,但是解决问题要有清晰的思路哈。学会一种技巧少走一些弯路,少花一些钱还是可以的。不过如果要赚钱,舍得花钱找技术开发更适合自己的网站,是很有必要的,花钱减少自己的时间浪费,也少出现一些不必要的麻烦,最重要的是专业的代码和业余的代码还是很大区别的。再者,一个很简单的道理“花钱就是投资”。

opencart技巧-opencart页面错误500的解决方法

其实不管是opencart,还是其他程序,错误500很大程度是代码有问题导致,为啥不报错呢?因为错误提示被关闭或者错误提示等级的设置问题。下面提供几个方案。

【其实这个文章不是解决500,而是让500的页面展示错误原因。然后根据错误解决。】

商店设置

商店设置的话,登陆admin后台,在:系统设置–>商店设置–>默认商店–>服务器这个TAB下。拉到最后面,就有对应的设置开启选项。开启即可。不过有时候开启了也是500哦。

服务器配置

这样的话就要修改php.ini,注意不是opencart根目录下的php.ini而是服务器环境的php.ini哦。如果是虚拟主机,提交服务单联系服务商修改。如果是VPS或者独立服务器,自己找到配置环境的php.ini打开修改。

不同环境文件所在路径不一样,win的一般情况在c:/windows/ 下面。

wamp在:!:\wamp\bin\php\phpxxx\php.ini

linux也各有不同,下面举例linux+lnmp

  1. # lnmp举例
  2. vi /usr/local/php/etc/php.ini
  3. # 按下 /  搜索 display_error 找到它
  4. /display_error
  5. # 如果是off,把off 改为 on
  6. # 如果搜索不到,自己添加一行
  7. display_error = On
  8. # 不熟悉SSH的看我以前的文章或者FTP下载修改。
  9. # 按下 inset 编辑,按下esc 退出编辑,按下 / 继续搜索
  10. /error_reporting
  11. # 后面改为 E_ALL | E_STRICT
  12. error_reporting = E_ALL | E_STRICT  

修改后按下ESC退出编辑,按下shift+Q,然后输入wq回车退出。

然后重启环境。比如 lnmp restart

截图:(截图的d没截到)

PHP代码

修改opencart的index.php 如果是后台就修改admin下的index.php,在 <?php 表情下面加如下代码即可在页面或者审核里输出错误日志。

  1. error_reporting(E_ALL); //E_ALL
  2. function cache_shutdown_error() {
  3.     $_error = error_get_last();
  4.     if ($_error && in_array($_error[‘type’], array(1, 4, 16, 64, 256, 4096, E_ALL))) {
  5.         echo ‘<font color=red>你的代码出错了:</font></br>’;
  6.         echo ‘致命错误:’ . $_error[‘message’] . ‘</br>’;
  7.         echo ‘文件:’ . $_error[‘file’] . ‘</br>’;
  8.         echo ‘在第’ . $_error[‘line’] . ‘行</br>’;
  9.     }
  10. }
  11. register_shutdown_function(“cache_shutdown_error”);

PHP这个代码来源朋友提供。

php技巧-把RSS内容写入数据库实例教程

有时候,你需要在一个自己另外的网站上调用文章,可是,你又懒得每次去录入更新,如果不在一个主机上,远程连接数据库又不是很好的注意,那么怎么办?抓取!

如果去写个抓取的程序,是比较麻烦的,而且,也可能带来临时的速度影响。好在,可以获取RSS,这样比较方面。

如何用php获取RSS的示例,我前面有写过一篇文章:http://blog.xukhost.com/2819.html

但是,这样的做法,会造成每次打开网站都变慢,而且如果另一个站挂了还会拖慢更多。那么怎么办呢?写个定时脚本,把抓取的数据写入数据库,但是每次打开页面是从数据库查询即可。大家先去看我前面的那个文章。然后得到一些代码,那么这里面有个地方可以利用,看这里:

  1. //构造输出字符串 ,显示的地方,可以自定义!
  2. $rss_str .= “<div class=\”result_list\”><a href='”.$link.“‘ target=_blank>”.$title.“</a></div><div class=\”line\”></div>”;
  3. $is_item = 0;

这个地方是把数据处理了,最后面 echo $rss_str; 的。那么,我们就修改这里,改为SQL语句即可。

  1. $sqlup = “INSERT INTO  `dbname`.`rss_news` (`id`,`title`,`link`) VALUES (”,  ‘”.$title.“‘,  ‘”.$link.“‘)”;
  2. mysql_query($sqlup,$mysql);
  3. $sqlin=mysql_insert_id();

当然了,你需要写一个连接数据库的配置信息,和建立相关的数据表和字段,详情查看我前面写的php教程:

http://blog.xukhost.com/3023.html   and  http://blog.xukhost.com/3064.html

数据库的话,可以执行下面的语句来添加数据表和字段:

  1. CREATE TABLE `sdt_news` (
  2.   `id` int(2) NOT NULL auto_increment,
  3.   `title` varchar(128) NOT NULL,
  4.   `link` varchar(64) NOT NULL,
  5.   UNIQUE KEY `id` (`id`)
  6. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;

这里会建立一个 sdt_news 的数据表,同时建立“id、title、link”三个字段。

请自己在本地环境测试该功能,完成后再上线,如果完全看不懂或者部分不懂,请付费联系解决。

QQ  184923973

php技巧-判断浏览器语言跳转不同页面

昨天有一个客户的需求,就是中文浏览器跳转另一个域名,他说自己的opencart买了个插件,插件会根据不同语言跳转不同的二级域名且显示中文,然后要求我帮忙改规则文件让中文的跳转另一个主域名,一开始我没多想,就根据他思路去改规则文件[当时脑袋短路吧],由于那个插件工作原理我不知道,因为我手上没有,又是付费的,所以我只能通过普通的规则文件写法写了重定向定义,可是那样不行,改来改去还是不行,后来我用了下下策,建立个cn子目录来实现,可还是有BUG,默认加载是不存在cn这个二级目录域名的,也就是就算我规则文件改了生效了,也需要点击那个中文的才会进入cn的二级目录[废话好多,进入正题]

于是我查了资料,写了下面的判断语句,自己本地用个php做测试

  1. <?php
  2. $language = substr($_SERVER[‘HTTP_ACCEPT_LANGUAGE’],0,5);
  3. if($language == “zh-cn”) header(“Location: http://cn.abc.com”);
  4. else header(“Location: http://abc.com”);
  5. ?>

可问题来了,在谷歌下不能判断,即使我改为zh也不行,我在火狐下倒是可以的,经过调整测试,和网上的资料,把第一行后面的5改为4,还是不行,不过后来还是搞定了,用下面这样的代码:

  1. <?php
  2. $language = substr($_SERVER[‘HTTP_ACCEPT_LANGUAGE’], 0, 4);
  3. if(preg_match(“/zh-c/i”$language)){
  4. header(“Location: http://cn.abc.com”);
  5. }elseif(preg_match(“/zh/i”$language)){
  6. header(“Location: http://cn.abc.com”);
  7. }else{
  8. header(“Location: http://abc.com”);
  9. }
  10. ?>

但是,我用火狐的时候,出现一个浏览器提示,说有一个不正确的重定向,嗯,于是我去掉了最后一句的else那一句,也就是直接判断,处理,默认情况不处理,当然了,看具体你的需求了,没有的情况不处理,则去掉第七八行,下面是几个语言的示例:

“/en/i” 英语
“/fr/i” 法语
“/de/i” 德语
“/jp/i” 日语
“/ko/i” 朝鲜
“/es/i” 西班牙语
“/sv/i” 瑞典

其他语言可以自己在网上搜索资料替换即可!

上面代码加在index.php 的最前面即可!

language-phpif