首页
留言
友情链接
壁纸
更多
关于
Search
1
dockerfile怎么执行shell脚本(利用tail -f /dev/null命令防止container启动后退出)
4,942 阅读
2
channel常见的异常总结
4,259 阅读
3
支付宝支付配置开发流程
1,403 阅读
4
HTTP 协议中的Content-Encoding
1,251 阅读
5
Laravel底层原理(二) —— 契约(Contracts)
939 阅读
PHP
composer
laravel
swoole
Docker
Linux
Go
随笔
mysql
nginx
Search
标签搜索
gopher
Docker
PHP
dockerfile
通道
go
defer
alipay
支付
git
phpstorm
IDEA
web安全
漏洞
socket
Royal
累计撰写
35
篇文章
累计收到
0
条评论
首页
栏目
PHP
composer
laravel
swoole
Docker
Linux
Go
随笔
mysql
nginx
页面
留言
友情链接
壁纸
关于
搜索到
14
篇与
PHP
的结果
2023-07-07
FFI扩展调用C的so动态库
什么是FFI? 此扩展允许在纯PHP中加载共享库(.DLL或.so),调用C函数以及访问C数据结构,而无需深入了解Zend扩展API。这个扩展需要安装 libffi libffi-devel库,编译安装步骤具体步骤就不说了(phpize、configure、make、make install四部曲),另外此扩展要求PHP版本必须是(PHP 7 >= 7.4.0, PHP 8),安装完通过php -m就可以看到下面的模块。FFI的API都有哪些?FFI::addr— 创建指向C数据的非托管指针FFI::alignof— 获取对齐方式FFI::arrayType— 动态构造一个新的C数组类型FFI::cast— 执行C类型转换FFI::cdef— 创建一个新的FFI对象FFI::free— 释放非托管数据结构FFI::isNull— 检查FFI \ CData是否为空指针FFI::load— 从C头文件加载C声明FFI::memcmp— 比较内存区域FFI::memcpy— 将一个存储区复制到另一个FFI::memset— 填充内存区域FFI::new— 创建一个C数据结构FFI::scope— 在预加载期间使用解析的C声明实例化FFI对象FFI::sizeof— 获取C数据或类型的大小FFI::string— 从内存区域创建一个PHP字符串FFI::type— 从C声明创建FFI \ CType对象FFI::typeof— 获取FFI \ CData的FFI \ CTypeFFI怎么用? 直接上例子,下面就是通过一个实例来说明FFI怎么调用C的动态库函数。首先通过FFI::cdef创建一个FFI对象,定义我们动态库中的常量、结构体、函数、以及通过地址加载我们的动态库。 define('ECCref_MAX_BITS', 512); define('ECCref_MAX_LEN', (ECCref_MAX_BITS + 7) / 8); define("SGD_SM3", 0x00000001); $this->ffi = FFI::cdef(<<<EOH // 定义结构体 typedef struct ECCrefPublicKey_st{ unsigned int bits; unsigned char *x; unsigned char *y; } ECCrefPublicKey; // 定义打开设备函数 int SDF_OpenDevice(void **phDeviceHandle); // 定义创建会话句柄函数 int SDF_OpenSession(void *hDeviceHandle, void **phSessionHandle); // 定义生成随机数函数 int SDF_GenerateRandom(void *hSessionHandle, unsigned int uiLength, unsigned char *pucRandom); // 定义杂凑运算初始化函数 int SDF_HashInit(void *hSessionHandle, unsigned int uiAlgID, ECCrefPublicKey *pucPublicKey, unsigned char *pucID, unsigned int uiIDLength); EOH , '/home/sangshuaidong/sdk/libcsapi.so');#加载动态库然后,我们在方法中进行调用c函数。public function openDevice() { $deviceHandlePtr = FFI::new("void*[1]"); $result = $this->ffi->SDF_OpenDevice($deviceHandlePtr); if ($result == 0) { $this->deviceHandle = $deviceHandlePtr[0]; return true; } else { return false; } } public function openSession() { $sessionHandlePtr = FFI::new("void*[1]"); $result = $this->ffi->SDF_OpenSession($this->deviceHandle, FFI::addr($sessionHandlePtr)); if ($result == 0) { $this->sessionHandle = $sessionHandlePtr[0]; return true; } else { return false; } } // 获取16位随机数 public function generateRandom($length) { $randomBuffer = FFI::new("unsigned char[$length]"); $result = $this->ffi->SDF_GenerateRandom($this->sessionHandle, $length, $randomBuffer); if ($result == 0) { $randomHex = bin2hex(FFI::string($randomBuffer, $length)); return $randomHex; } else { return false; } } // hash杂凑运算初始化 public function hashInit($algID = "SGD_SM3", $length = 0) { $result = 0; if ($algID === 'SGD_SM3') { $publicKey =$this->ffi->new("ECCrefPublicKey"); $publicKey->bits = 0; $unsignedCharType = FFI::arrayType(FFI::type('unsigned char'), [ECCref_MAX_LEN]); $publicKey->x = FFI::cast('unsigned char*', FFI::new($unsignedCharType)); $publicKey->y = FFI::cast('unsigned char*', FFI::new($unsignedCharType)); $result = $this->ffi->SDF_HashInit( $this->sessionHandle, SGD_SM3, FFI::addr($publicKey), FFI::addr(FFI::new("unsigned char")), $length ); } else { // 其他算法的处理,根据实际情况进行设置 } if ($result == 0) { return true; } else { return false; } } 最后,我们通过执行可执行程序可以看到成功输出!
2023年07月07日
239 阅读
0 评论
1 点赞
2022-04-12
php设计模式(三)----工厂方法模式
应用场景:要实例化的对象充满不确定性可能会改变的时候;要创建的对象的数目和类型是未知的;结构:工厂方法UML图工厂方法模式包含如下角色:Product接口类:用于定义产品规范;具体的产品实现,例如ConcreateProductA、ConcreateProductB;抽象工厂类IFactory:用于规范工厂;具体产品创建的简单工厂,例如ConcreateFactoryA、ConcreateFactoryB。相比简单工厂 ,创建对象这件事不再交由一个类来创建:把简单工厂拆分,每个产品由专门的一个简单工厂来实现,每个简单工厂实现工厂接口类。这样实现在同一等级结构中,支持增加任意产品。代码实现:ICar.php定义产品规范<?php namespace SimpleFactory; interface ICar { public function driver(); } 具体产品实现<?php namespace SimpleFactory; class Benz implements ICar { public function driver() { echo 'benz driver.'; } } class Bmw implements ICar { public function driver() { echo 'bmw driver.'; } } 抽象工厂类IFactory<?php namespace Factory; interface IFactory { public static function makeCar(); } 具体工厂实现namespace Factory; class FactoryBenz implements IFactory { public static function makeCar() { return new Benz(); } } class FactoryBmw implements IFactory { public static function makeCar() { return new Bmw(); } }客户端使用<?php // 客户端 $car = FactoryBenz::makeCar(); $car->driver(); // 输出 benz driver.
2022年04月12日
145 阅读
0 评论
0 点赞
2022-04-09
php设计模式(二)----简单工厂模式
应用场景:工厂类负责创建的对象比较少;由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂;客户端只知道传入工厂类的参数,对于如何创建对象不关心;结构:简单工厂模式包含如下角色:Factory(工厂角色)工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有实例的内部逻辑;工厂类可用直接被外界调用,创建所需要的产品对象;在工厂类中提供了静态的工厂方法factoryMethod(),它返回一个抽象产品类Product,所有的具体产品都是抽象产品的子类。Product(抽象产品角色)抽象产品角色是简单工厂模式所创建的所有对象的分类,负责描述所有实例所共有的公共接口,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个工厂方法,因为所有创建的具体产品对象都是其子类对象ConcreteProduct(具体产品角色)具体产品角色是简单工厂模式的创建目标,所有创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现定义在抽象产品中的抽象方法。代码实现:抽象产品角色Protuct.php<?php // 抽象产品角色 interface Product { public function play(); }具体产品角色productA.php<?php // 具体产品角色A require_once 'Product.php'; class productA implements Product { public function play() { // TODO: Implement play() method. echo 'productA play...'; } }具体产品角色productB.php<?php //具体产品角色B class productB implements Product { public function play() { // TODO: Implement play() method. echo 'productB play...'; } }工厂角色Factory.php<?php // 工厂类 require_once 'productA.php'; require_once 'productB.php'; class Factory { public function __construct($product) { if($product=='productA'){ echo '工厂生产productA'.PHP_EOL; $pro= new productA(); $pro->play(); }elseif ($product=='productB'){ echo '工厂生产productB'.PHP_EOL; $pro= new productB(); $pro->play(); }else{ echo '工厂暂不生产'; } } }.客户端使用<?php // 客户端 require_once 'Factory.php'; $factory=new Factory('productA'); // 输出productA play...
2022年04月09日
231 阅读
0 评论
0 点赞
2022-04-09
php设计模式(一)----单例模式
应用场景:数据库连接这种比较耗费资源的操作;我们希望整个应用只实例化一个;结构:4私1公或者3私一公(私有化重建方法非必须)私有化构造方法: 防止使用 new 创建多个实例;私有化克隆方法: 防止 clone 多个实例;私有化重建方法: 防止反序列化;私有化静态属性: 防止直接访问存储实例的属性;公有化静态方法。代码实现:class Singleton { //创建静态私有的变量保存该类对象 static private $instance; //防止使用new直接创建对象 private function __construct(){ } //防止使用clone克隆对象 private function __clone(){ } //防止反序列化 private function __wakeup(){ } static public function getInstance() { //判断$instance是否是Singleton的对象,不是则创建 if (!self::$instance instanceof self) { self::$instance = new self(); } return self::$instance; } public function test() { echo "我是一个单例模式"; } } $sing = Singleton::getInstance(); $sing->test(); $sing2 = new Singleton(); //Fatal error: Uncaught Error: Call to private Singleton::__construct() from invalid context in $sing3 = clone $sing; //Fatal error: Uncaught Error: Call to private Singleton::__clone() from context
2022年04月09日
250 阅读
0 评论
1 点赞
2022-01-14
Laravel底层原理(四) —— 控制反转(IOC)
什么是 IoC 控制反转(Inversion of Control,缩写为 IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称 DI),还有一种方式叫 “依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。 — 维基百科 简单说来,就是一个类把自己的的控制权交给另外一个对象,类间的依赖由这个对象去解决。依赖注入属于依赖的显示申明,而依赖查找则是通过查找来解决依赖。Laravel 中的使用 注入一个类:App::bind('foo', function($app) { return new FooBar; });这个例子的意思是创建一个别名为 foo 的类,使用时实际实例化的是 FooBar。使用这个类的方法是:$value = App::make('foo');$value 实际上是 FooBar 对象。如果希望使用单例模式来实例化类,那么使用:App::singleton('foo', function() { return new FooBar; });这样的话每次实例化后的都是同一个对象。实现「控制反转」,有两种方式:Dependency Injection (DI) - 依赖注入Dependency Lookup - 依赖查找哪些方面的「控制」被「反转」了? 依赖对象的「获得」被反转了。Class A 中用到了 Class B 的对象 b,一般情况下,需要在 A 的代码中显式的 new 一个 B 的对象。采用依赖注入技术之后,A 的代码只需要定义一个私有的 B 对象,不需要直接 new 来获得这个对象,而是通过相关的 容器控制程序 来将 B 对象在外部 new 出来并注入到 A 类里的引用中。而具体获取的方法、对象被获取时的状态由 容器 来指定。假设我有一个 iPhone,我的 iPhone 依赖充电器才能充电。class iPhone { // 电量 private $power; // 充电 public function charge() { } }我还有个苹果原装充电器:class AppleCharger { public function charge() { return 100; } }在以前,iPhone 内部「控制」着只能用哪一款充电器:class iPhone { // 电量 private $power; // 充电,只能用原装的充电器 public function charge() { $charger = new AppleCharger; $this->power = $charger->charge(); } }// 充电 $iphone = new iPhone; $iphone->charge();使用依赖注入之后,我来决定给 iPhone 用哪一款充电器:class iPhone { private $power; private $charger; // 依赖注入充电器,╮(╯▽╰)╭哎算了只要是充电器就行 public function __construct(Charger $charger) { $this->charger = $charger; } // 充电 public function charge() { $this->power = $this->charger->charge(); } }interface Charger { public function charge(); }// Laravel 容器 use Illuminate\Container\Container; $container = Container::getInstance(); // 给它一个原装充电器: $container->bind(Charger::class, AppleCharger::class); // 或者给它其它充电器 $container->bind(Charger::class, OtherCharger::class); // 充电 $iphone = $container->make(iPhone::class); $iphone->charger();可见,使用依赖注入之后,控制权「反转」了,由外部来决定给它什么充电器 (依赖对象)。Laravel 管这个 容器控制程序 叫 Service Container (服务容器),它来控制着各种依赖的获取方法
2022年01月14日
484 阅读
0 评论
0 点赞
1
2
3