首页
复制
搜索
前进
后退
重载网页
和我当邻居
给我留言吧
首页
统计
关于
WOW怀旧
友链
更多
留言
壁纸
直播
Search
1
关于《杀死那个石家庄人》背后的故事
3,797 阅读
2
沈阳故宫之旅
609 阅读
3
摄影记录|鸿恩寺
562 阅读
4
赤壁赋| 知不可乎骤得,托遗响于悲风
423 阅读
5
Laravel-admin 删除行|删除回调
366 阅读
编程技术
GoLang
Vue
PHP
Linux
Redis
网络安全
生活杂记
登录
Search
标签搜索
PHP
随笔
Mysql
Laravel-Admin
Laravel
摄影
设计模式
Ab
Linux
Javascript
MAC
支付
CentOs
sh
嘉陵江
南滨路
蓝易云
redis
万能青年
累计撰写
60
篇文章
累计收到
142
条评论
首页
栏目
编程技术
GoLang
Vue
PHP
Linux
Redis
网络安全
生活杂记
页面
统计
关于
WOW怀旧
友链
留言
壁纸
直播
搜索到
23
篇与
的结果
2022-03-07
PHP之trait的用法
trait{callout color="#f0ad4e"}PHP 实现了一种代码复用的方法,称为 traitphp从以前到现在一直都是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性{/callout}{message type="info" content="例子"/}<?php trait Dog{ public $name="dog"; public function bark(){ echo "This is dog"; } } class Animal{ public function eat(){ echo "This is animal eat"; } } class Cat extends Animal{ use Dog; public function drive(){ echo "This is cat drive"; } } $cat = new Cat(); $cat->drive(); echo "<br/>"; $cat->eat(); echo "<br/>"; $cat->bark(); 输出结果为: This is cat drive This is animal eat This is dog ?>优先级#1{callout color="#f0ad4e"}从基类继承的成员被插入的 SayWorld Trait 中的 MyHelloWorld 方法所覆盖。其行为 MyHelloWorld 类中定义的方法一致。优先顺序是当前类中的方法会覆盖 trait 方法,而 trait 方法又覆盖了基类中的方法。{/callout}<?php class Base { public function sayHello() { echo 'Hello '; } } trait SayWorld { public function sayHello() { parent::sayHello(); echo 'World!'; } } class MyHelloWorld extends Base { use SayWorld; } $o = new MyHelloWorld(); $o->sayHello(); ?>结果为Hello World!{dotted startColor="#ff6c6c" endColor="#1989fa"/}优先级#2<?php trait HelloWorld { public function sayHello() { echo 'Hello World!'; } } class TheWorldIsNotEnough { use HelloWorld; public function sayHello() { echo 'Hello Universe!'; } } $o = new TheWorldIsNotEnough(); $o->sayHello(); ?>结果为Hello Universe!详情可查阅php手册:https://www.php.net/manual/zh/language.oop5.traits.php
2022年03月07日
145 阅读
0 评论
0 点赞
2022-03-06
PHP生成器Yield的用法
优点1.节省大量内存2.优化性能3.比较适合计算大量数据举个栗子<?php function createRange($number){ $data = []; for($i=0;$i<$number;$i++){ $data[] = time(); } return $data; } $result = createRange(10); foreach($result as $value){ sleep(1); echo $value.'<br />'; }来看看他的结果{callout color="#f0ad4e"}在调用函数 createRange 的时候给 $number 的传值是10,一个很小的数字。假设,现在传递一个值10000000(1000万)。那么,在函数 createRange 里面,for循环就需要执行1000万次。且有1000万个值被放到 $data 里面,而$data数组在是被放在内存内。所以,在调用函数时候会占用大量内存。{/callout}创建生成器<?php function createRange($number){ $data = []; for($i=0;$i<$number;$i++){ // $data[] = time(); yield time(); } // return $data; } $result = createRange(10); foreach($result as $value){ sleep(1); echo $value.' -- '; }打印结果{message type="info" content="结论:输出的值和第一次没有使用生成器的不一样,这里的值(时间戳)中间间隔了1秒。"/}{callout color="#f0ad4e"}未使用生成器时:createRange 函数内的 for 循环结果被很快放到 $data 中,并且立即返回。所以, foreach 循环的是一个固定的数组。使用生成器时:createRange 的值不是一次性快速生成,而是依赖于 foreach 循环。foreach 循环一次, for 执行一次。{/callout}执行流程首先调用 createRange 函数,传入参数10,但是 for 值执行了一次然后停止了,并且告诉 foreach 第一次循环可以用的值。foreach 开始对 $result 循环,进来首先 sleep(1) ,然后开始使用 for 给的一个值执行输出。foreach 准备第二次循环,开始第二次循环之前,它向 for 循环又请求了一次。for 循环于是又执行了一次,将生成的时间戳告诉 foreachforeach 拿到第二个值,并且输出。由于 foreach 中 sleep(1) ,所以, for 循环延迟了1秒生成当前时间所以,整个代码执行中,始终只有一个记录值参与循环,内存中也只有一条信息。无论开始传入的 $number 有多大,由于并不会立即生成所有结果集,所以内存始终是一条循环的值。生成器yield关键字不是返回值,他的专业术语叫产出值,只是生成一个值
2022年03月06日
193 阅读
0 评论
0 点赞
2022-03-06
PHP函数eval:一句话木马
前景1.在一个系统文件上传逻辑处理不严谨时2.php危险函数未禁用我是谁含义: eval — 把字符串作为PHP代码执行警告 函数eval()语言结构是 非常危险的,因为它允许执行任意 PHP 代码。它这样用是很危险的。如果您仔细的确认过,除了使用此结构以外 别无方法,请多加注意, 不要允许传入任何由用户 提供的、未经完整验证过的数据文件上传漏洞首先这里我用docker搭建了一个简单的bWAPP 实验环境文件上传漏洞是什么?关键词:绕过 文件上传(File Upload)是大部分应用都具备的功能, 例如用户上传附件、改头像、分享图片等 文件上传漏洞是开发者没有做充足验证(包括前端、后端)的情况下,允许用户上传恶意文件,这里上传的文件可以是木马、病毒、恶意脚本或者webshell等这里我编写了一个php文件并上传到了这个实验环境<?php @eval($_POST['hack']); ?>这里通过点击我们轻松访问到了上传的文件,并发现后端并没有去检测处理这个文件这个时候我们就可以通过curl去访问这个文件,由于之前写入的是POST请求,所以我们这里入参也是通过POST的形式get_current_user() 函数返回当前 PHP 脚本所有者名称。getcwd() 函数取得当前工作目录{message type="info" content="所以,在渗透过程中,如果系统逻辑性不是很严谨,我们可以通过这种方式来进行网络渗透,获取对方数据信息。当然,在我们的日常开发中,也是需要规避此类风险的。"/}
2022年03月06日
277 阅读
0 评论
1 点赞
2022-03-06
PHP八大设计模式
单例模式{callout color="#f0ad4e"}$_instance必须声明为静态的私有变量构造函数和析构函数必须声明为私有,防止外部程序new 类从而失去单例模式的意义getInstance()方法必须设置为公有的,必须调用此方法 以返回实例的一个引用::操作符只能访问静态变量和静态函数new对象都会消耗内存使用场景:最常用的地方是数据库连接。使用单例模式生成一个对象后, 该对象可以被其它众多对象所使用。私有的__clone()方法防止克隆对象单例模式,使某个类的对象仅允许创建一个。构造函数private修饰,申明一个static getInstance方法,在该方法里创建该对象的实例。如果该实例已经存在,则不创建。比如只需要创建一个数据库连接。{/callout}{message type="info" content="示例"/}<?php namespace App\Http\Controllers\Admin; use Lcobucci\JWT\Builder; use Lcobucci\JWT\Parser; use Lcobucci\JWT\Signer\Hmac\Sha256; use Lcobucci\JWT\ValidationData; class JwtAuth { private $token; private $user_id; private $secrect="#awadakvcabzijvjvsuvr"; private $aud="www.test.com"; private $iss="www.test.com"; private $decodeToken; /** * JTW句柄 * @var */ private static $instance; public static function getInstance(){ if (is_null(self::$instance)){ self::$instance =new self(); } return self::$instance; } private function __construct() { } private function __clone(){ } public function getToken(){ return (string)$this->token; } public function setToken($token){ $this->token = $token; return $this; } public function setUid($user_id){ $this->user_id =$user_id; return $this; } public function encode(){ $time= time(); $this->token = (new Builder()) ->setHeader('alg','HS256') ->setIssuer($this->iss) ->setAudience($this->aud) ->setIssuedAt($time) ->setExpiration($time+3600) ->set('user_id',$this->user_id) ->sign(new Sha256(), $this->secrect) ->getToken(); return $this; } /** * @return \Lcobucci\JWT\Token */ public function decode(){ if (!$this->decodeToken){ $this->decodeToken = (new Parser())->parse((string)$this->token); $this->user_id = $this->decodeToken->getClaim('user_id'); } return $this->decodeToken; } /** * @return bool */ public function validate(){ $data = new ValidationData(); $data->setIssuer($this->iss); $data->setAudience($this->aud); return $this->decode()->validate($data); } /** * @return bool */ public function verify(){ $result = $this->decode()->verify(new Sha256() , $this->secrect); return $result; } public function getUid(){ return (new Parser())->parse((string)$this->token)->getClaim('user_id'); } }{message type="info" content="调用"/}$jwtAuth = JwtAuth::getInstance(); $token = $jwtAuth->setUid($id)->encode()->getToken();工厂模式{callout color="#f0ad4e"}工厂模式,工厂方法或者类生成对象,而不是在代码中直接new。 使用工厂模式,可以避免当改变某个类的名字或者方法之后,在调用这个类的所有的代码中都修改它的名字或者参数。{/callout}{message type="info" content="示例"/} // 最基本的工厂模式 class Myname{ public function OutPutMyName(){ return 'hello world~'; } } class NameFactory{ public static function Namefunc(){ return new Myname(); } } $obj=NameFactory::Namefunc(); echo $obj->OutPutMyName(); ?> {message type="warning" content="抽象工厂模式"/}{callout color="#f0ad4e"}抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。{/callout}<?php //定义一个抽象类 abstract class operation { protected $_numA = 0; protected $_numB = 0; protected $_result = 0; public function __construct($a, $b) { $this->_numA = $a; $this->_numB = $b; } //抽象方法所有子类必须实现该方法 protected abstract function getResult(); } //加法运算 class operationAdd extends operation { public function getResult() { $this->_result = $this->_numA + $this->_numB; return $this->_result; } } //减法运算 class operationSub extends operation { public function getResult() { $this->_result = $this->_numA - $this->_numB; return $this->_result; } } //乘法运算 class operationMul extends operation { public function getResult() { $this->_result = $this->_numA * $this->_numB; return $this->_result; } } //除法运算 class operationDiv extends operation { public function getResult() { $this->_result = $this->_numA / $this->_numB; return $this->_result; } } //定义工厂类 class operationFactory { //创建保存示例的静态成员变量 private static $obj; //创建实例的静态方法 public static function CreateOperation($type, $a, $b) { switch ($type) { case '+': self::$obj = new operationAdd($a, $b); break; case '-': self::$obj = new operationSub($a, $b); break; case '*': self::$obj = new operationMul($a, $b); break; case '/': self::$obj = new operationDiv($a, $b); break; } //最后返回这个实例 return self::$obj; } } //最后我们使用工厂模式 $obj = operationFactory::CreateOperation('+', 100, 20); echo $obj->getResult(); 如果还是理解不了这两者的区别,可以看看这个帖子: https://www.zhihu.com/question/20367734注册模式{callout color="#f0ad4e"}单例模式保证了一个类中只有一个实例被全局访问,当你有一组全局对象被全局访问时可能就需要用到注册者模式 (registry),它提供了在程序中有条理的存放并管理对象 (object)一种解决方案。一个“注册模式”应该提供get() 和 set()方法来存储和取得对象(用一些属性key)而且也应该提供一个isValid()方法来确定一个给定的属性是否已经设置。 注册模式通过单一的全局的对象来获取对其它对象的引用{/callout}{message type="info" content="示例"/}class Registry { protected static $store = array(); private static $instance; public static function instance() { if(!isset(self::$instance)) { self::$instance = new self(); } return self::$instance; } public function isValid($key) { return array_key_exists($key,Registry::$store); } public function get($key) { if (array_key_exists($key,Registry::$store)) return Registry::$store[$key]; } public function set($key, $obj) { Registry::$store[$key] = $obj; } } //数据库链接类 class ConnectDB { private $host; private $username; private $password; private $conn; public function __construct($host, $username, $password){ $this->host = $host; $this->username = $username; $this->password = $password; } public function getConnect() { return mysql_connect($this->host,$this->username,$this->password); } } $reg = Registry::instance(); $reg->set('db1', new ConnectDB('localhost', 'root', '123456')); $reg->set('db2', new ConnectDB('127.0.0.2', 'test', 'test')); print_r($reg->get('db1')); print_r($reg->get('db2'));{callout color="#f0ad4e"}注册模式,解决全局共享和交换对象。已经创建好的对象,挂在到某个全局可以使用的数组上,在需要使用的时候,直接从该数组上获取即可。将对象注册到全局的树上。任何地方直接去访问。{/callout}{message type="info" content="示例"/}class Register { //定义全局属性 protected static $objects; //将对象注册到全局的树上 function set($alias,$object) { //将对象放到树上 self::$objects[$alias]=$object; } static function get($name){ //获取某个注册到树上的对象 return self::$objects[$name]; } function _unset($alias) { //移除某个注册到树上的对象。 unset(self::$objects[$alias]); } }适配器模式(interface){callout color="#f0ad4e"}将各种截然不同的函数接口封装成统一的API。 PHP中的数据库操作有MySQL,MySQLi,PDO三种,可以用适配器模式统一成一致,使不同的数据库操作,统一成一样的API。类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致。 首先定义一个接口(有几个方法,以及相应的参数)。然后,有几种不同的情况,就写几个类实现该接口。将完成相似功能的函数,统一成一致的方法。{/callout}{message type="info" content="示例"/}// 接口 IDatabase <?php namespace IMooc; interface IDatabase { function connect($host, $user, $passwd, $dbname); function query($sql); function close(); }MySQL <?php namespace IMooc\Database; use IMooc\IDatabase; class MySQL implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = mysql_connect($host, $user, $passwd); mysql_select_db($dbname, $conn); $this->conn = $conn; } function query($sql) { $res = mysql_query($sql, $this->conn); return $res; } function close() { mysql_close($this->conn); } }PDO <?php namespace IMooc\Database; use IMooc\IDatabase; class PDO implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = new \PDO("mysql:host=$host;dbname=$dbname", $user, $passwd); $this->conn = $conn; } function query($sql) { return $this->conn->query($sql); } function close() { unset($this->conn); } }{message type="info" content="示例二"/}/** * 目标角色 */ interface Target { /** * 源类也有的方法1 */ public function sampleMethod1(); /** * 源类没有的方法2 */ public function sampleMethod2(); } /** * 源角色 */ class Adaptee { /** * 源类含有的方法 */ public function sampleMethod1() { echo 'Adaptee sampleMethod1 <br />'; } } /** * 类适配器角色 */ class Adapter extends Adaptee implements Target { /** * 源类中没有sampleMethod2方法,在此补充 */ public function sampleMethod2() { echo 'Adapter sampleMethod2 <br />'; } } class Client { /** * Main program. */ public static function main() { $adapter = new Adapter(); $adapter->sampleMethod1(); $adapter->sampleMethod2(); } }策略模式{callout color="#f0ad4e"}策略模式,将一组特定的行为和算法封装成类,以适应某些特定的上下文环境。 eg:假如有一个电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有的广告位展示不同的广告。在传统的代码中,都是在系统中加入各种if else的判断,硬编码的方式。如果有一天增加了一种用户,就需要改写代码。使用策略模式,如果新增加一种用户类型,只需要增加一种策略就可以。其他所有的地方只需要使用不同的策略就可以。 首先声明策略的接口文件,约定了策略的包含的行为。然后,定义各个具体的策略实现类。{/callout}{message type="info" content="示例"/}UserStrategy.php <?php /* * 声明策略文件的接口,约定策略包含的行为。 */ interface UserStrategy { function showAd(); function showCategory(); }FemaleUser.php <?php require_once 'Loader.php'; class FemaleUser implements UserStrategy { function showAd(){ echo "2016冬季女装"; } function showCategory(){ echo "女装"; } }MaleUser.php <?php require_once 'Loader.php'; class MaleUser implements UserStrategy { function showAd(){ echo "IPhone6s"; } function showCategory(){ echo "电子产品"; } }Page.php//执行文件 <?php require_once 'Loader.php'; class Page { protected $strategy; function index(){ echo "AD"; $this->strategy->showAd(); echo "<br>"; echo "Category"; $this->strategy->showCategory(); echo "<br>"; } function setStrategy(UserStrategy $strategy){ $this->strategy=$strategy; } } $page = new Page(); if(isset($_GET['male'])){ $strategy = new MaleUser(); }else { $strategy = new FemaleUser(); } $page->setStrategy($strategy); $page->index();php策略模式和适配器模式的区别{callout color="#c5d54d"}PHP中策略模式和适配器模式的区别是:策略模式是通过定义算法,并将算法封装起来,使算法独立于客户而独立变化;适配器模式是使用已经存在的类,将其适配成自己需要的形式。{/callout}观察者模式(Observer){callout color="#f0ad4e"}(Observer),首先要有一个被观察的角色,但ta是【唯一的】。虽然"表演者"只有一个但是"观众"有很多,既一群"人"围观一个"人"。既然有无数个观察者,那么我们需要知道都有哪一些"人"。所以我们需要一个“容器”来记录这些"人",一个类似于数组一样来储存所有观察者的容器。一个"演员"(被观察者),一群"观众"(观察者),一台"摄影机"(记录容器){/callout}1.抽象主题(Subject)角色:主题角色将所有对观察者对象的引用保存在一个集合中,每个主题可以有任意多个观察者。 抽象主题提供了增加和删除观察者对象的接口。2.抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在观察的主题发生改变时更新自己。3.具体主题(ConcreteSubject)角色:存储相关状态到具体观察者对象,当具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。4.具体观察者(ConcretedObserver)角色:存储一个具体主题对象,存储相关状态,实现抽象观察者角色所要求的更新接口,以使得其自身状态和主题的状态保持一致主题接口interface Subject{ public function register(Observer $observer); public function notify(); }观察者接口interface Observer{ public function watch(); }{message type="info" content="Subject就是被观察者,Observer就是观众,也就是观察者"/}被观察者class Action implements Subject{ public $_observers=array(); public function register(Observer $observer){ $this->_observers[]=$observer; } public function notify(){ foreach ($this->_observers as $observer) { $observer->watch(); } } }{message type="info" content="Action实现了被观察者接口,他现在就是被观察者,再定义一个$_observers数组,他就是记录观众的容器了。首先实现register方法,用它传入一个观察者,然后塞到数组里,再实现notify()方法,它会遍历容器数组,执行每个观察者的watch()方法。"/}观察者class Cat implements Observer{ public function watch(){ echo "Cat watches TV<hr/>"; } } class Dog implements Observer{ public function watch(){ echo "Dog watches TV<hr/>"; } } class People implements Observer{ public function watch(){ echo "People watches TV<hr/>"; } }{message type="info" content="这里定义了三个观察者,全都实现了Observer接口,前面的Subject会循环调用每个观察者的watch()方法,所以我们需要实现每个观察者的watch()方法。"/}调用$action=new Action(); $action->register(new Cat()); $action->register(new People()); $action->register(new Dog()); $action->notify();{message type="info" content="首先new被观察者对象,执行它的register()方法,把每个观察者都放入容器数组,最后执行notify()方法,通知所有观察者执行自己的方法。"/}原型模式{callout color="#f0ad4e"}为了避免创建对象的成本,使用标准方法 new foo() 创建一个原型并克隆它。{/callout}场景大数据量 ( 例如:通过 ORM 模型一次性往数据库插入 1,000,000 条数据 ) 。 {message type="info" content="示例"/}<?php abstract class BookPrototype { /* * @var string */ protected $title; /* * @var string */ protected $category; abstract public function __clone(); public function getTitle(): string { return $this->title; }// getTitle() end public function setTitle($title) { $this->title = $title; }// setTitle() end }// BookPrototype{} end class BarBookPrototype extends BookPrototype { /* * @var string */ protected $category = 'Bar'; public function __clone() { } }// BarBookPrototype{} end class FooBookPrototype extends BookPrototype { /* * @var string */ protected $category = 'Foo'; public function __clone() { } }// FooBookPrototype{} end $fooPrototype = new FooBookPrototype(); $barPrototype = new BarBookPrototype(); for ($i = 0; $i < 10; $i++) { $book = clone $fooPrototype; $book->setTitle('Foo Book No ' . $i); echo $book->getTitle() . PHP_EOL; } for ($i = 0; $i < 5; $i++) { $book = clone $barPrototype; $book->setTitle('Bar Book No ' . $i); echo $book->getTitle() . PHP_EOL; }结果<?php Foo Book No 0 Foo Book No 1 Foo Book No 2 Foo Book No 3 Foo Book No 4 Foo Book No 5 Foo Book No 6 Foo Book No 7 Foo Book No 8 Foo Book No 9 Bar Book No 0 Bar Book No 1 Bar Book No 2 Bar Book No 3 Bar Book No 4{message type="info" content="PHP 对象复制 : 对象复制可以通过 clone 关键字来完成"/}装饰器模式{callout color="#f0ad4e"}动态地给一个对象添加一些额外的职责,就增加功能来说,Decorator模式相比生成子类更为灵活{/callout}{message type="info" content="例子"/}短信模板接口 <?php interface MessageTemplate { public function message(); }假设有很多模板实现了上面的短信模板接口// 下面这个是其中一个优惠券发送的模板实现 class CouponMessageTemplate implements MessageTemplate { public function message() { return '优惠券信息:我们是全国第一的牛X产品哦,送您十张优惠券!'; } }我们来准备好装饰上面那个过时的短信模板abstract class DecoratorMessageTemplate implements MessageTemplate { public $template; public function __construct($template) { $this->template = $template; } } 过滤新广告法中不允许出现的词汇class AdFilterDecoratorMessage extends DecoratorMessageTemplate { public function message() { return str_replace('全国第一', '全国第二', $this->template->message()); } } 使用我们的大数据部门同事自动生成的新词库来过滤敏感词汇,这块过滤不是强制要过滤的内容,可选择使用class SensitiveFilterDecoratorMessage extends DecoratorMessageTemplate { public $bigDataFilterWords = ['牛X']; public $bigDataReplaceWords = ['好用']; public function message() { return str_replace($this->bigDataFilterWords, $this->bigDataReplaceWords, $this->template->message()); } } 客户端,发送接口,需要使用模板来进行短信发送 class Message { public $msgType = 'old'; public function send(MessageTemplate $mt) { // 发送出去咯 if ($this->msgType == 'old') { echo '面向内网用户发送' . $mt->message() . PHP_EOL; } else if ($this->msgType == 'new') { echo '面向全网用户发送' . $mt->message() . PHP_EOL; } } } $template = new CouponMessageTemplate(); $message = new Message(); // 老系统,用不着过滤,只有内部用户才看得到 $message->send($template); // 新系统,面向全网发布的,需要过滤一下内容哦 $message->msgType = 'new'; $template = new AdFilterDecoratorMessage($template); $template = new SensitiveFilterDecoratorMessage($template); // 过滤完了,发送吧 $message->send($template);引用:https://zhuanlan.zhihu.com/p/102420902 及 https://www.cnblogs.com/yuanwanli/p/8796402.html
2022年03月06日
290 阅读
0 评论
1 点赞
2022-02-28
笔记|Lumen请求webservice服务
首先封装一个请求方法 /** * @param $uri //webservice 地址 * @param $xml //xml主体 * @param $fuc //方法 * @param $data //请求参数 * @return false * */ public function sendSoap($uri, $xml,$fuc,$data) { ini_set("soap.wsdl_cache_enabled", 0); libxml_disable_entity_loader(false); $class_name = __CLASS__; try { $soap = new \SoapClient($uri, ['soap_version' => SOAP_1_2, "trace" => 1,'cache_wsdl' => 0, 'connection_timeout' => 10]); $soap->__setLocation($uri); logMessage('【SOAP请求:】' . $xml , $class_name); switch ($fuc) { case 'GetClinicItem': // 调用函数 $result_xml = $soap->__soapCall($fuc, []);//调用方式2 logMessage('【SOAP返回:】' . $result_xml->GetClinicItemResult, $class_name); return $result_xml->GetClinicItemResult; break; case 'GetClinicItemDetail': // 调用函数 $result_xml = $soap->__soapCall($fuc, $data);//调用方式2 logMessage('【SOAP返回:】' . $result_xml->GetClinicItemDetailResult, $class_name); return $result_xml->GetClinicItemDetailResult; break; } } catch (\SoapFault $fault) { logMessage('【SoapFault:】' . $fault->getMessage(), $class_name); return false; } catch (\Exception $exception) { logMessage('【SOAP报错:】' . $exception->getMessage(), $class_name); return false; } }调用此方法 $xml =<<<XML <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> <soapenv:Header/> <soapenv:Body> <tem:GetClinicItem/> </soapenv:Body> </soapenv:Envelope> XML; $result_xml = $this->sendSoap([webservice地址], $xml,[方法名],[传参]);踩坑传参是个二位数组 例如:$data=[['节点名称'=>'val']];有莫名其秒的报错时,可以加一下这两个配置在请求前ini_set("soap.wsdl_cache_enabled", 0); libxml_disable_entity_loader(false);
2022年02月28日
266 阅读
0 评论
0 点赞
1
...
3
4
5