Laravel 中优雅的跨域


2019-02-15 10:38
zpq
5

其实要想跨域网上教程多的是.
举例:

  1. Google搜索出来的结果就是在 web.php 或 api.php 文件加上
header('Access-Control-Allow-Origin : *');
header('Access-Control-Allow-Headers : Content-Type,X-Auth-Token,Authorization,Origin');
header('Access-Control-Allow-Methods :GET, POST, PUT, DELETE, OPTIONS');

说实话真是简单粗暴! 既然我们选择了laravel 那当然一定要优雅 : )
2. 还有一种就是用开源包 barryvdh/laravel-cors也是方便的,当然我们在使用的时候也应该知其然而所以然

这边记录下我自己写的方法,

Unicode 空白字符 \u00a0


2018-07-18 22:41
zpq
52

最近在做网页抓取数据这块遇到一个神奇的问题

php 中的 trim 函数一直不能去空,也差了很多资料,说是空白字符。
就索性用 json_encode 一下,果然发现问题,会有一个\u00a0 字符
搜了下意思是 不换行空格。。

其他的空格描述

swoole 整合 laravel


2018-05-04 15:28
zpq
122

php常见运行方式

  1. php + module + apache
  2. php + php-fpm + nginx

传统运行方式优点

  1. 每次都是新的请求,运行完即释放,不占用内存

传统运行方式缺点

  1. 每次都需要composer 引入文件
  2. DB contention 开销大,每次运行都要建立连接和执行查询,大多数性能消耗在连接上

基于swoole http 容器

swoole 有一个优点就是他可以常驻内存,不需要反复引用,类似于JAVA里的Spring Boot
DB contention 也可以有连接池不需要每次执行完就断开连接,减少连接次数。

整合代码

关于MySql列别名做查询条件的问题


2018-05-02 10:36
zpq
27

假如有这样一条sql语句

select name as name1 from table1 where name1='aaa'

mysql 中不可以这样使用别名,那可不可以用其他什么方式来代替 ?

首先 字段别名不能直接在谓词部分引用
这个查询可以改成这样:

select name as name1 from table1 having (name1='aaa')

12306 抢票脚本 基于laravel console


2018-01-18 17:37
zpq
498

主要接口

  1. POST https://kyfw.12306.cn/otn/login/checkUser 验证用户是否登录
  2. GET https://kyfw.12306.cn/otn/login/init 登录页面初始化
  3. GET https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&0.123456789 获取验证码图像接口 末尾是随机数
  4. POST https://kyfw.12306.cn/passport/captcha/captcha-check 验证码验证
  5. POST https://kyfw.12306.cn/passport/web/login 登录请求
  6. POST https://kyfw.12306.cn/passport/web/auth/uamtk 获取uamtk 我也不知道是什么玩意
  7. POST https://kyfw.12306.cn/otn/uamauthclient 最后登录成功
  8. POST https://kyfw.12306.cn/otn/passengers/init 获取乘车人 其实乘车人可以在请求提交订单接口时通过html 正则匹配可以获取,作为抢票工具来说,当然先确定好,后面就只顾抢票就行了。
  9. GET https://kyfw.12306.cn/otn/leftTicket/query 车次查询
  10. POST https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest 请求提交订单
  11. POST https://kyfw.12306.cn/otn/confirmPassenger/initDc 请求订单初始化
  12. POST https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo 请求验证订单信息
  13. POSThttps://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue 确认订单信息

laravel 5.4 redis 报错 'Predis\Response\ServerException' with message 'ERR unknown command 'EVAL''


2017-06-15 17:33
zpq
833

在laravel 5.2 迁移到 5.4 出现错误

这个错误不是框架错误 是 redis 版本 过低导致的 !!

redis eval 命令必须在版本 >= 2.6.0

之前安装redis的时候是用yum命令安装的。

安装的版本是2.4.10 找不到高版本的yum安装方式

没办法只能编译安装

编译安装官网也有,这里顺便也复制下来

wget http://download.redis.io/releases/redis-3.2.9.tar.gz
tar xzf redis-3.2.9.tar.gz
cd redis-3.2.9
make
src/redis-server
src/redis-cli

redis 默认是前台运行的 后台运行需要修改配置文件redis.conf
大约在 128 行

# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize no

no 改成 yes 保存 然后执行命令

./redis-server [/path/to/redis.conf]

laravel 5.4 报错SQLSTATE[42000] Syntax error or access violation 1055 'xxx' isn't in GROUP BY


2017-06-09 12:30
zpq
175

查询mysql 1055错误码发现问题为在mysql的配置中如果设置了sql_mode包含ONLY_FULL_GROUP_BY值得话,在进行查询时需要将select的字段都包含在group by 中。
即 select x,y from xxx group by x,y
否则就会报错

但是查看自己的配置my.cnf发现在sql_mode中并没有ONLY_FULL_GROUP_BY这个值

然后去查看Laravel的配置文件,config/database.php,查找mysql的配置,

'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => env('DB_PREFIX',''),
            'strict' => true,
            'engine' => null,
        ],

发现有个strict项,默认为true,上网也没有查找到相关解释,根据字面意思猜测可能为是否开启严格模式,将其修改为false,再次测试发现问题解决,可以输出正确结果
源代码解释
vendor\laravel\framework\src\Illuminate\Database\Connectors\MySqlConnector.php 约144行

protected function setModes(PDO $connection, array $config)
    {
        if (isset($config['modes'])) {
            $this->setCustomModes($connection, $config);
        } elseif (isset($config['strict'])) {
            if ($config['strict']) {		//这边有个判断如果是true则执行strictMode()方法所以要改为false
                $connection->prepare($this->strictMode())->execute();
            } else {
                $connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();
            }
        }
    }
protected function strictMode()
    {
        return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'";
    }

也可以编辑 /etc/my.cnf 文件
在**[mysqld]**追加

~~```
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"


~~重启mysql即可。~~

微信支付报错“支付签名验证失败”


2017-06-01 22:06
zpq
145

微信支付有几个地方需要注意的

  • sign 签名时需要在末尾增加key参数 key 参数在商户后台进行设置 sign签名验证
  • wx.config 签名验证工具 url 参数必须是当前js运行所在的url(包括参数) 如果签名失败可能跟支付的授权目录有关
  • 微信创建统一订单时返回的数据格式中只有prepay_id参数有用,其他返回的参数无用
  • wx.chooseWXpay 在调起微信支付时需要二次签名(sign签名),其中有个地方需要注意(巨坑)。具体二次签名如下
$appid = 'appid';              //appid
$randstr = '123123213213';     //随机字符串
$time = '123456789';           //时间戳
$key = 'keyyyyyyyy';           //商户后台设置的key
$prepayid = 'wx2017060115493564b5a926a10145685802';//假设统一订单返回的prepayid
$prepayid = 'prepay_id='.$prepayid;//这里要组装(我是坑)
        $signstr = "appId={$appid}&nonceStr={$randstr}&package={$prepayid}&signType=MD5&timeStamp={$time}&key={$key}";
//生成需要签名的字符串为
//appId=appid&nonceStr=123123213213&package=prepay_id=wx2017060115493564b5a926a10145685802&signType=MD5&timeStamp=123456789&key=keyyyyyyyy";
$paysign = strtoupper(md5($signstr));
//data 为返回为前台数据
$data = [
    'nonceStr' => $randstr,
    'timestamp' => $time,
    'signType' => 'MD5',
    'paySign' => $paysign,
    'package' => $prepayid,
];
  • wx.chooseWXpay 中有个参数timestamp 不是timeStamp 需要签名的时间戳都是timeStamp js里的都是小写的。

laravel 生成 sitemap


2017-05-03 22:41
zpq
153

什么是 Sitemap?

Sitemap 可方便管理员通知搜索引擎他们网站上有哪些可供抓取的网页。最简单的 Sitepmap 形式,就是 XML 文件,在其中列出网站中的网址以及关于每个网址的其他元数据(上次更新的时间、更改的频率以及相对于网站上其他网址的重要程度为何等),以便搜索引擎可以更加智能地抓取网站。
网络抓取工具通常会通过网站内部和其他网站上的链接查找网页。Sitemap 会提供此数据以便允许支持 Sitemap 的抓取工具抓取 Sitemap 提供的所有网址,并了解使用相关元数据的网址。使用 Sitemap 协议并不能保证网页会包含在搜索引擎中,但可向网络抓取工具提供一些提示以便它们更有效地抓取网站。

Sitemaps XML 格式

本文件说明 Sitemap 通讯协定的 XML 配置。
Sitemap 通讯协定格式是由 XML 标记所组成。Sitemap 中的所有资料值都必须是实体逸出。档案本身必须使用 UTF-8 编码。
Sitemap 必须:

  • 以起始 标记做为开头,并以结束 标记做为结尾。
  • 指定 内的名称领域 (通讯协定标准)。
  • 让每个 URL 中包含一个 项目做为母层 XML 标记。
  • 在每个 母层标记包含一个 子层项目。

其他所有标记均为选用的。是否支援这些选用的标记须视搜寻引擎而定。详细资讯请参阅各搜寻引擎的说明文件。
另外,Sitemap 中所有的 URL 必须来自单一主机,例如 www.example.com 或 store.example.com。

XML Sitemap 范例

下列范例显示仅包含一个 URL 并使用所有选用标记的 Sitemap。选用标记以斜体表示。