Deprecated
: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in
/www/wwwroot/testblog.58heshihu.com/var/Widget/Archive.php
on line
1057
首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
182 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
28
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
31
篇与
的结果
2023-08-12
PHP的可调用类型(callable)总结
PHP的可调用类型(callable)总结// 1 普通函数 call_user_func('my_function'); // 2类的静态方法 call_user_func(['MyClass', 'myCallbackMethod']); // 3对象方法 call_user_func([new MyClass(), 'myCallbackMethod']); //4类的静态方法(2) call_user_func('MyClass::myCallbackMethod'); //5匿名函数 call_user_func(function(){echo '匿名函数';}); //6箭头函数 call_user_func(fn() =>print('箭头函数')); //7相对关系 call_user_func(array('B', 'parent::who')); // 8: Objects implementing __invoke can be used as callables class C { public function __invoke($name) { echo 'Hello ', $name, "\n"; } }$c = new C(); call_user_func($c, 'PHP!'); ?>其它用法:call_user_func(__NAMESPACE__ .'\Foo::test'); // As of PHP 5.3.0 call_user_func(array(__NAMESPACE__ .'\Foo', 'test')); // As of PHP 5.3.0 class myclass { static function say_hello() { echo "Hello!\n"; } } $classname = "myclass"; call_user_func(array($classname, 'say_hello')); call_user_func($classname .'::say_hello'); // As of 5.2.3 $myobject = new myclass(); call_user_func(array($myobject, 'say_hello'));
2023年08月12日
12 阅读
0 评论
0 点赞
2023-08-11
谈谈PHP中的匿名函数与闭包
谈谈PHP中的匿名函数与闭包<?php //匿名函数,说白了就是“没有名字的函数”,不多说。给一段代码可能更为明白: //例一,定义匿名函数并调用 $str='world'; $func=function ($str) { echo 'hello '.$str; }; $func($str);// 输出 hello world //例二,定义匿名函数,用use 引入变量并调用 $str='world'; $func=function () use ($str) { echo 'hello '.$str; }; $func();//输出 hello world //例三 //在函数中把匿名函数返回,并且调用它 function getPrintStrFunc() { $func = function ($str) { echo $str; }; return $func; } $printStrFunc = getPrintStrFunc(); $printStrFunc('some string'); // 例四 //把匿名函数当做参数传递,并且调用它,这里实现了先定义参数 ,再传入函数的效果(和普通的函数先定义函数,再传入参数调用相反) function callFunc($func) { $func('some string'); } $printStrFunc = function ($str) { echo $str; }; callFunc($printStrFunc); //也可以直接将匿名函数进行传递。如果你了解js,这种写法可能会很熟悉 callFunc(function ($str) { echo $str; }); // 匿名函数和普通函数最大的区别是在于,匿名函数可以作为一个具体的“值”赋予给变量或者对象属性,其次,由于匿名函数可以被定义在不同地方,使得他可以有效利用他所在的局域内的变量(或者说上下文中的变量)。下面例子中就是这样一种情况。 class foo { public function exec(Closure $callback) { echo $callback(); } } $name = 'nick'; (new foo)->exec(function () use ($name) { return 'hi, '. $name; }); // 输出: hi, nick // 我们可以看到,匿名函数使用了上下文中的变量$name。而实际上,这个匿名函数是在另一个地方被执行(是在foo类里面被执行的)。这样使得我们不必将变量name的值通过参数传递到类foo的exec方法中,而且可以减少在exec方法中不必要的处理逻辑,使得类更容易专注于自己的职责。 // 匿名函数的作用还有很多,要知道,函数定义的时候是不会执行的,除非被调用。上文中例子其实就是这样,我们可以看到,例子中,对$name变量的处理是在方法exec被调用后才发生,且利用了匿名函数被定义时的上下文中的变量。这种特性,我们可以利用来实现一个控制反转(IoC)容器。 /** * 一个简单的IoC容器 */ class Container { protected static $bindings; public static function bind($abstract, Closure $concrete) { static::$bindings[$abstract] = $concrete; } public static function make($abstract) { return call_user_func(static::$bindings[$abstract]); } } /** * 示例用的 talk 类 */ class talk { public function greet($target) { echo 'hi, ' . $target->getName(); } } /** * 示例用的 A 类 */ class A { public function getName() { return 'Nick'; } } /** * 示例用的 B 类 */ class B { public function getName() { return 'Amy'; } } // 以下代码是主要示例代码 // 创建一个talk类的实例 $talk = new talk; // 将A类绑定至容器,命名为foo Container::bind('foo', function () { return new A; }); // 将B类绑定至容器,命名为bar Container::bind('bar', function () { return new B; }); // 通过容器取出实例 $talk->greet(Container::make('foo')); // hi, Nick $talk->greet(Container::make('bar')); // hi, Amy // 上述例子中,只有在通过make方法获取实例的时候,实例才被创建,这样使得我们可以实现容器,我们依照这一特性,还可以更多的实现高级的特性如事件触发等。利用好匿名函数,可以让应用变得更加丰满。 //彩蛋 匿名函数还可以这样调用:) (function ($name) { echo 'My name is ' . $name; })('jack ma'); // 输出: My name is jack ma
2023年08月11日
12 阅读
0 评论
0 点赞
2023-08-11
PHP 7.4 FFI(外部函数接口)
PHP外部函数接口:FFI,是一个PHP扩展,允许您轻松地将一些外部库包含到PHP代码中。这意味着可以直接在PHP中使用C,Go,Rust等共享库,而无需在C中编写PHP扩展。这个概念在其他语言(如Python或Go)中已经存在多年了。UUID生成让我们从一个小例子开始:UUID生成。PHP 7.4 FFI(外部函数接口)使用PHP,有几种生成UUID的方法。最好的方法是使用PECL UUID扩展名。您可以在GitHub上阅读其代码。这个PHP扩展负责将PHP函数绑定到libuuid。要使其正常工作,您必须在系统上安装libuuid(不必担心,几乎总是这样)和PECL。这就是我们从PHP用户代码调用uuid_create()时发生的情况:your PHP code+---+-------------^---+ v ^+---v-------------+---+ | PHP engine | +---+-------------^---+ v ^+---v-------------+---+ | UUID ext | +---+-------------^---+ v ^+---v-------------+---+ | UUID lib | +---------------------+FFI承诺用纯PHP代码替换“ UUID扩展”层。在讨论PHP扩展或FFI层之前,我们需要解释什么是库。库通常是用C编写的。但是也可以用许多其他可以编译为共享库的语言来编写:C ++,Rust,Go等。在unix或linux上,该库将被编译成一个.so文件。在Windows上它将是一个.dll文件。也可以将库静态包含到二进制文件中,但是本章不在本文的讨论范围之内。在库代码源中,有.h文件。它们包含库能够执行的操作。这是uuid.h文件的摘录:…Some constants:define UUID_VARIANT_NCS 0define UUID_VARIANT_DCE 1define UUID_VARIANT_MICROSOFT 2define UUID_VARIANT_OTHER 3Some function declarations:void uuid_generate(uuid_t out);int uuid_compare(const uuid_t uu1, const uuid_t uu2);…一个.h文件类似于PHP接口的东西:它含有常量和函数签名。FFI/UUID 层为了工作,FFI 需要我们想要使用的基础库 (libuuid) 的函数签名。因此,我们将.h文件复制到我们的项目中。有时,您可以清理并调整此文件以满足您的需要。例如,您可以删除永远不会使用的函数。这就是我们的文件的样子:define FFI_LIB "libuuid.so.1"typedef unsigned char uuid_t[16];extern void uuid_generate_time(uuid_t out); // v1extern void uuid_generate_md5(uuid_t out, const uuid_t ns, const char *name, size_t len); // v3extern void uuid_generate_random(uuid_t out); // v4extern void uuid_generate_sha1(uuid_t out, const uuid_t ns, const char *name, size_t len); // v5这是最重要的,也是编写代码中更复杂的部分。完成后,我们可以将此文件包含在我们的PHP代码中:$ffi = FFI::load(__DIR__ . '/include/uuid-php.h');我们现在可以直接从PHP代码中使用libuuid。容易,不是吗?但等一下,libuuid不能完全那样工作。所有函数都期望一些类型化的参数,您可能已经看到过。这些函数不返回 UUID,但将通过引用第一个参数进行修改。因此,在调用 函数之前,我们需要此值:$output = $ffi->new('uuid_t');$output是的实例FFI\CData。根据的内部类型,CData由于文档中描述了不同的运算符,我们可以访问不同的值。最后,我们可以调用我们的函数。uuid_generate_random()匹配.h文件中库公开的名称:$ffi->uuid_generate_random($output);$output的内容将用组成 UUID 的十进制值数组进行更新。现在,我们需要将此数组转换为十六进制值的字符串:foreach ($output as $values[]);$uuid = sprintf('%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x', ...$values);你喜欢它吗?如果您不想麻烦复制它,我们为您制作了它,并且它是开源的:https: //github.com/jolicode/ffi-uuid🍾一些想法简单外部库的绑定确实很容易。最复杂的部分是创建最小 .h文件,并将PHP类型映射到库,反之亦然。性能看看我们实现的性能也很有趣。在我们的存储库中,您可以找到一个基准脚本。这是我们的实现与PECL之间进行比较的结果:FFI:[v1] 1.254s[v4] 5.301sPECL:[v1] 0.626s[v4] 4.583s可以看到,PECL比我们的UUID V1实现快两倍,但对于UUID V4仅快15%。我们可以很容易地解释一下:UUID V4仅由伪随机数据组成,而UUID V1包含许多静态块。获取随机数据有点慢,这就是为什么V4生成要慢得多的原因。在V4上,这两种实现的区别不明显,因为几乎所有时间都花在了内部libuuid。我们可以得出什么结论?FFI确实还很年轻(在撰写本文时甚至没有发布)。因此,我们可以期待一些性能上的改进。但是我们已经可以说:如果本机扩展已经存在并且可以安装,请使用它:如果扩展不存在,那么FFI是一个很好的候选项;如果应用程序中存在瓶颈,在 C、Rust 等中移植这些代码位并将其绑定到 FFI 可能很有趣。当 CPU 受限制时,FFI 会变得非常有趣:DOM 管理、大阵列、复杂计算等。原来的扩展是否将替换为FFI?现在说还真为时过早。但是,某些扩展(例如PDO)不仅仅具有简单绑定到库的功能。我非常有信心这些扩展将不会被FFI取代。但是,某些扩展可能会被替换。php-redis,amqp,uuid等就是这种情况。例如Remi Collet已经开始使用FFI来代替redis扩展。FFI敞开了大门:可以替换一些纯PHP库,而改用低级库。gitlib可以使用带有FFI的libgit2就是这种情况。在某些情况下,没有C扩展,也没有纯PHP实现。如果您曾经尝试在PHP中测试TensorFlow,您会知道它很复杂。Dmitry Stogov是最重要的PHP Core贡献者之一,也是PHP / FFI的作者,他创建了一个POC来将TensorFlow绑定到PHP。选择哪种语言将lib绑定到PHP?能够编译到共享库(.so)的所有语言在系统上都不能很好地绑定到PHP。最好使用没有运行时的语言(C / C ++ / Rust /…),因为运行时可能会有副作用。例如,在GO中,运行时具有垃圾回收器并管理goroutine的线程。这可能会降低执行速度,甚至破坏您的应用程序。如何将Rust lib绑定到PHP?我想尝试一下用另一种语言比PHP执行复杂的计算是否更快。从网页提取HTML片段是很常见的:为了测试您的网站,或在爬网时。Joel创建了一个小型库,用于提取与CSS表达式匹配的文档的第一个HTML元素。该代码确实很短,在某种程度上,Rust类型向C Type的转换代表了代码的2/3以上。PHP绑定看起来与UUID非常相似。但是这里我们将.so直接包含在源代码中:$ffi = FFI::cdef(<<<EOHconst char cssfilter(const char html, const char *filter);EOH, __DIR__.'/../target/release/libcssfilter.so');而且用法更简单:$value = $ffi->cssfilter($html, $selector);性能确实令人印象深刻,令人鼓舞:FFI: Duration: 1.731ssymfony/crawler: Duration: 2.321s我们可以轻松得出结论,如果计算复杂,将一部分PHP代码移植到另一种语言以提高应用程序性能可能非常有趣。结论FFI是个好东西。即使绑定尚不存在,FFI也会允许我们尝试一些库。它将使我们可以用Rust(例如)植入替换代码的某些慢速部分。而且我敢肯定,它将解锁一些我们还没有的想法。
2023年08月11日
10 阅读
0 评论
0 点赞
2023-08-11
PHP里如何获取函数的调用位置
PHP里如何获取函数的调用位置<?php function c() { a(); } function a() { b(); } function b() { $backtrace = debug_backtrace(); $aa= array_shift($backtrace); var_dump($aa); } c(); /* 输出 array(4) { ["file"]=> string(14) "/code/main.php" ["line"]=> int(6) ["function"]=> string(1) "b" ["args"]=> array(0) { } } */ ?>
2023年08月11日
19 阅读
0 评论
0 点赞
2023-08-11
PHP 7.4中的箭头函数
PHP 7.4中的箭头函数短闭包(也称为箭头函数)是用PHP编写短函数的一种方式。当将闭包传递给类似array_map或array_filter的函数时,此符号很有用。这是他们的样子:// A collection of Post objects$posts = [/ … /];$ids = array_map(fn($post) => $post->id, $posts);以前,您必须编写以下代码:$ids = array_map(function ($post) {return $post->id;}, $posts);让我们总结一下如何使用短闭包。自PHP 7.4起可用他们以fn关键字开头它们只能有一个表达式,即return语句不允许return关键字参数和返回类型可以类型提示上面示例的更严格类型的编写方式可能是:$ids = array_map(fn(Post $post): int => $post->id, $posts);还有两件事要提到:还可以使用展开运算符允许引用,这两个参数都作为返回值如果要通过引用返回值,则应使用以下语法:fn&($x) => $x简而言之,除了仅允许一个表达式之外,短闭包还具有与普通闭包相同的功能。没有多行您没看错:短闭包只能有一个表达式。这意味着您不能包含多行。理由如下:短闭包的目标是减少冗长。 fn当然比function所有情况都短。RFC的创建者Nikita Popov辩称,如果您要处理多行功能,则使用短闭包将带来的好处更少。毕竟,按照定义,多行闭包已经更加冗长;因此能够跳过两个关键字(function和return)不会有太大的区别。您是否同意这种观点取决于您。虽然我可以在项目中想到许多单行闭包,但也有很多多行闭包,在这些情况下,我个人会错过简短的语法。不过还是有希望的:将来有可能添加多行短闭包,但这只是一个RFC。来自外部范围的值短闭包和普通闭包之间的另一个显着区别是,短闭包不需要use关键字能够从外部范围访问数据。$modifier = 5;array_map(fn($x) => $x * $modifier, $numbers);请务必注意,不允许从外部作用域修改变量。值由值绑定,而不是由引用约束。这意味着您可以在短闭包内更改$modifier,尽管它不会对外部作用域中的$modifier变量产生影响当然有一个例外是$this关键字,它的作用与普通的闭包完全相同:array_map(fn($x) => $x * $this->modifier, $numbers);未来的可能性我已经提到了多行短关闭,这仍然是未来的可能性。浮动的另一个想法是允许在类中使用短闭包语法,例如,用于getter和setterclass Post {private $title; fn getTitle() => $this->title;}总而言之,短闭包是一个受欢迎的功能,尽管仍有改进的空间。最大的一个可能是多行短闭包。
2023年08月11日
20 阅读
0 评论
0 点赞
1
...
3
4
5
...
7