比如我想快速查看php某个扩展的版本号, 可以用如下命令来快速查看
php --ri swoole
php –ri 命令就是专门用来查看php扩展信息的, 后面直接加上扩展的name就好
今天莫名其妙的出现了如下错误
php -v
dyld: Library not loaded: /usr/local/opt/jpeg/lib/libjpeg.8.dylib
Referenced from: /usr/local/bin/php
Reason: image not found
[1] 24433 abort php -v
解决办法是重新安装下libjpeg.8.dylib这个包
wget -c http://www.ijg.org/files/jpegsrc.v8d.tar.gz
tar xzf jpegsrc.v8d.tar.gz
cd jpeg-8d
./configure
make
cp ./.libs/libjpeg.8.dylib /usr/local/opt/jpeg/lib
ps: 如果编译之后找不到libjpeg.8.dylib这个文件, 可以用如下命令查找文件位置
find / -name libjpeg.8.dylib
安装python的mysql驱动的时候, 可以通过下面两种方式来安装 1
pip install mysql-connector-python --allow-external mysql-connector-python (pip install mysql-connector)
2 从mysql官网下载下来安装
https://dev.mysql.com/downloads/connector/c/
但是不管哪种方式安装都碰到了一个error, 安装不成功, 错误信息类似于
Unable to find Protobuf include directory.
最开始怀疑是这个驱动包不支持python3, 后来用pyhton2试了一下还是不行(ps: 安装python3的驱动的时候将pip命令替换为pip3即可), 后来发现是版本的问题, 具体支持到哪个版本请自行查阅, 安装的时候带上版本号就可以了
pip3 install mysql-connector==2.1.4
目前版本是2.1.4, 再高的版本没有试过
最近公司项目开发过程中有场景用到了观察者模式, 记录一下 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力。当对象们连接在一起时, 它们就可以相互提供服务和信息。这个模式对于大型系统项目来说应该是挺挺有用的,通俗的讲, 这种模式允许某个类去观察另一个类。当一个类被改变时,观察类就会收到通知并且做出相应的动作
在平时的项目中还是挺有用的,比如一个用户下了一笔订单,下单成功后,就需要去发送短信/邮件的通知,库存的修改,账户余额的修改等等很多操作。
在之后的PHP5.0起,内置的SPL标准库中就提供了这种设计模式接口供大家使用,接下了就通过实例来学习一下。
SPL 提供了 SplSubject 和 SplObserver 接口。 SplSubject 接口提供了attach()、detach()、notify() 三个方法。而 SplObserver 接口则提供了 update()方法。
<?php
/**
* 这一模式的概念是SplSubject类维护了一个特定状态,当这个状态发生变化时,它就会调用notify()方法。
* 调用notify()方法时,所有之前使用attach()方法注册的SplObserver实例的update方法都会被调用。
*
*/
interface SplSubject{
public function attach(SplObserver $observer);//注册观察者
public function detach(SplObserver $observer);//释放观察者
public function notify();//通知所有注册的观察者
}
interface SplObserver{
public function update(SplSubject $subject);//观察者进行更新状态
}
使用所提供的接口,来实现观察者模式
<?php
/**
*具体目标
*/
class Salary implements SplSubject {
private $observers, $money;
public function __construct() {
$this->observers = array();
}
public function attach(SplObserver $observer) { //注册观察者
$this->observers[] = $observer;
}
public function detach(SplObserver $observer) { //释放观察者
if($idx = array_search($observer,$this->observers,true)) {
unset($this->observers[$idx]);
}
}
public function notify() { //通知所有观察者
foreach($this->observers as $observer) {
$observer->update($this);
}
}
public function payoff($money) { //发工资方法
$this->money = $money;
$this->notify(); //通知观察者
}
}
/**
* 具体观察者
*/
class Programmer1 implements SplObserver {
public function update(SplSubject $subject) {
echo 'Programmer1 发工资了!<br/>';
}
}
class Programmer2 implements SplObserver {
public function update(SplSubject $subject) {
echo 'Programmer2 也发工资了!<br/>';
}
}
$subject = new Salary();
$observer1 = new Programmer1();
$observer2 = new Programmer2();
//注册观察者
$subject->attach($observer1);
$subject->attach($observer2);
//发工资操作,发起通知
$subject->payoff('20K');
通过Observer模式,把一对多对象之间的通知依赖关系的变得更为松散,大大地提高了程序的可维护性和可扩展性,也很好的符合了开放-封闭原则。东西是不错,如何能够更好的去使用它,仍需要多加实践、联系
今天微信开发的时候碰到了一个问题, 接收不到微信推送过来的消息, 后来查明是因为php7中$GLOBALS[‘HTTP_RAW_POST_DATA’]被废弃了, 可以使用 file_get_contents( ‘php://input’ ) 来获取, 可以在代码中判断是否可以用 $GLOBALS[‘HTTP_RAW_POST_DATA’] 来获取值
存在我很脑子里的很长时间的一个观念终于改变了, 以前总喜欢搞些看起来高大上的代码, 不爱写业务代码, 喜欢钻研新技术, 新的工具, 对老的技术嗤之以鼻, 对不喜欢的技术比如css, html等极度排斥, 现在觉的不管写什么, 其实都能锻炼你的某方面能力, 希望以后的自己 可以放平心态, 什么都可以做, 能写php, python, shell, 做的了dba, 码的了vue, 写的了业务代码, 搞得了服务器, 成为一个小的全栈工程师, 最近做的生成图片的功能比较多, 主要功能代码记录一下:
<?php
// 字体28-21, 32-24
// 一行股票高度 141 , 两行股票高度 202
$stockNum = 5;
$mainTitleText = "- 6月21日值得关注潜力股 -";
$font = '/usr/local/var/PingFang.ttc';
$circle = '/usr/local/var/circle.png';
$mainTitlePadding = padding($mainTitleText, 22.5);
// 股票文本
$text = array(
'西的我的', '网络', '发发福', 'dfd'
);
$padding = array();
$circles = array(
array('/usr/local/var/circle.png'),
array('/usr/local/var/circle.png', '/usr/local/var/circle.png'),
array('/usr/local/var/circle.png', '/usr/local/var/circle.png', '/usr/local/var/circle.png'),
array('/usr/local/var/circle.png', '/usr/local/var/circle.png', '/usr/local/var/circle.png' , '/usr/local/var/circle.png'),
array('/usr/local/var/circle.png', '/usr/local/var/circle.png', '/usr/local/var/circle.png', '/usr/local/var/circle.png', '/usr/local/var/circle.png'),
array('/usr/local/var/circle.png', '/usr/local/var/circle.png', '/usr/local/var/circle.png', '/usr/local/var/circle.png', '/usr/local/var/circle.png', '/usr/local/var/circle.png'),
);
$count = count($text);
$fontSize = 25;
$backgroundHeight = ($count > 3) ? 204 : 148;
$im = imagecreatetruecolor(750, $backgroundHeight);
// 定义各种颜色
$white = imagecolorallocate($im, 255, 255, 255);
$red = imagecolorallocate($im, 223, 84, 82);
$black = imagecolorallocate($im, 0, 0, 0);
$yellow = imagecolorallocate($im, 240, 140, 51);
$blue = imagecolorallocate($im, 106, 142, 208);
$colors = array(
array($red),
array($red, $yellow),
array($red, $yellow, $blue),
array($red, $yellow, $blue, $red),
array($red, $yellow, $yellow, $blue, $red),
array($blue, $red, $yellow, $yellow, $blue, $red),
);
// 创建底层画布
imagefilledrectangle($im, 0, 0, 750, $backgroundHeight, $white);
// 总共分为两排, 第一排的数量 ($count - 3) 个, 第二个 3个
if ($count - 3 > 0) {
// 主标题
imagettftext($im, 22.5, 0, (750 - $mainTitlePadding['width']) / 2, 52, $black, $font, $mainTitleText);
// 获得字体的宽度和高度
foreach ($text as $key => $value) {
$padding[] = padding($value, $fontSize);
}
$circle = $circles[$count - 1];
$color = $colors[$count - 1];
$before3Stocks = array_slice($text, 0, $count - 3, true);
$next3Stocks = array_slice($text, $count -3, 3, true);
$multi30 = count($before3Stocks) - 1 > 0 ? count($before3Stocks) - 1 : 0;
$j = 0;
foreach ($before3Stocks as $before => $beforeStockName) {
$oneCircle = file_get_contents($circle[$before]);
$oneCircle = imagecreatefromstring($oneCircle);
imagecopyresized($im, $oneCircle, (750 - 196 * count($before3Stocks) - 30*$multi30) / 2 + 30 * $j + 196 * $j, 79,0,0,196, 48,imagesx($oneCircle),imagesy($oneCircle));
imagettftext($im, 26, 0, (750 - 196 * count($before3Stocks) - 30 * $multi30) / 2 + 196*$j + 30*$j + (196 - $padding[$before]['width']) / 2, 115, $color[$before], $font, $before3Stocks[$before]);
$j = $j + 1;
}
$oneCircle = ''; // 重新初始化
// 第二排
$i = 0;
foreach ($next3Stocks as $k => $stockName) {
$oneCircle = file_get_contents($circle[$k]);
$oneCircle = imagecreatefromstring($oneCircle);
imagecopyresized($im, $oneCircle, (750 - 196 * 3 - 30 *2) / 2 + 30 * $i + 196 * $i, 136,0,0,196, 48,imagesx($oneCircle),imagesy($oneCircle));
imagettftext($im, $fontSize, 0, (750 - 196 * 3 - 30*2) / 2 + 196 * $i + 30 * $i + (196 - $padding[$k]['width']) / 2, 76 + (48 - $padding[$k]['height']) / 2 + 30 + 60, $color[$k], $font, $stockName);
$i = $i + 1;
}
} else {
// 主标题
imagettftext($im, 22.5, 0, (750 - $mainTitlePadding['width']) / 2, 52, $black, $font, $mainTitleText);
// 获得字体的宽度和高度
foreach ($text as $key => $value) {
$padding[] = padding($value, $fontSize);
}
$circle = $circles[$count - 1];
$color = $colors[$count - 1];
$multi30 = count($text) - 1 > 0 ? count($text) - 1 : 0;
$j = 0;
foreach ($text as $k2 => $stockName) {
$oneCircle = file_get_contents($circle[$k2]);
$oneCircle = imagecreatefromstring($oneCircle);
imagecopyresized($im, $oneCircle, (750 - 196 * count($text) - 30*$multi30) / 2 + 30 * $j + 196 * $j, 79,0,0,196, 48,imagesx($oneCircle),imagesy($oneCircle));
imagettftext($im, 26, 0, (750 - 196 * count($text) - 30 * $multi30) / 2 + 196*$j + 30*$j + (196 - $padding[$k2]['width']) / 2, 115, $color[$k2], $font, $stockName);
$j = $j + 1;
}
}
header("Content-type: image/png");
imagepng($im);
imagedestroy($im);
// 返回文案的高度和宽度
function padding($text, $size)
{
$font = $font = '/usr/local/var/PingFang.ttc';
$largeText = imagettfbbox($size, 0, $font, $text);
$width = $largeText[2] - $largeText[6]; // 文字宽度
$height = $largeText[3] - $largeText[7];
return array(
'width' => $width,
'height' => $height
);
}
结果如下: