eloquent/pops
最新稳定版本:5.0.0
Composer 安装命令:
composer require eloquent/pops
包简介
PHP object proxy system.
README 文档
README
No longer maintained
This package is no longer maintained. See this statement for more info.
Pops
PHP Object Proxy System.
Installation and documentation
- Available as Composer package eloquent/pops.
What is Pops?
Pops is a system for wrapping PHP objects in other objects to modify their behaviour. A Pops proxy will, as much as possible, imitate the object it wraps. It passes along method calls and returns the underlying result, and allows transparent access to properties (for both setting and getting).
Pops is the underlying system behind Liberator.
Creating proxies
Let's write a simple proxy that converts everything to uppercase. Here we have a class:
class Confusion { public function wat() { return "What is this? I don't even..."; } public $derp = 'Has anyone really been far even as decided to use even?'; }
And here is our proxy:
use Eloquent\Pops\ProxyObject; class UppercaseProxyObject extends ProxyObject { public function popsCall($method, array &$arguments) { return strtoupper(parent::popsCall($method, $arguments)); } public function __get($property) { return strtoupper(parent::__get($property)); } }
We use popsCall() here rather than __call() to get around PHP limitations to
do with passing arguments by reference. See calling methods with by-reference
parameters for a deeper explanation.
Now when we access wat() and $derp both normally, and through our proxy, we
can see the effect:
$confusion = new Confusion; $proxy = new UppercaseProxyObject($confusion); echo $confusion->wat(); // outputs "What is this? I don't even..." echo $proxy->wat(); // outputs "WHAT IS THIS? I DON'T EVEN..." echo $confusion->derp; // outputs 'Has anyone really been far even as decided to use even?' echo $proxy->derp; // outputs 'HAS ANYONE REALLY BEEN FAR EVEN AS DECIDED TO USE EVEN?'
Recursive proxies
Pops proxies can be applied to any value recursively. This comes in handy when designing, for example, an output escaper (similar to Symfony). Here's an example of how such a system could be created for escaping HTML output:
namespace OutputEscaper; use Eloquent\Pops\Proxy; /** * Escapes output for use in HTML. */ class OutputEscaperProxy extends Proxy { /** * Get the array proxy class. * * @return string The array proxy class. */ protected static function proxyArrayClass() { return __NAMESPACE__ . '\OutputEscaperProxyArray'; } /** * Get the class proxy class. * * @return string The class proxy class. */ protected static function proxyClassClass() { return __NAMESPACE__ . '\OutputEscaperProxyClass'; } /** * Get the object proxy class. * * @return string The object proxy class. */ protected static function proxyObjectClass() { return __NAMESPACE__ . '\OutputEscaperProxyObject'; } /** * Get the proxy class for primitive values. * * @return string The proxy class for primitive values. */ protected static function proxyPrimitiveClass() { return __NAMESPACE__ . '\OutputEscaperProxyPrimitive'; } }
namespace OutputEscaper; use Eloquent\Pops\ProxyArray; /** * Wraps an array to escape any sub-values for use in HTML. */ class OutputEscaperProxyArray extends ProxyArray { /** * Get the proxy class. * * @return string The proxy class. */ protected static function popsProxyClass() { return __NAMESPACE__ . '\OutputEscaperProxy'; } }
namespace OutputEscaper; use Eloquent\Pops\ProxyClass; /** * Wraps a class to escape any sub-values for use in HTML. */ class OutputEscaperProxyClass extends ProxyClass { /** * Get the proxy class. * * @return string The proxy class. */ protected static function popsProxyClass() { return __NAMESPACE__ . '\OutputEscaperProxy'; } }
namespace OutputEscaper; use Eloquent\Pops\ProxyObject; /** * Wraps an object to escape any sub-values for use in HTML. */ class OutputEscaperProxyObject extends ProxyObject { /** * Get the proxy class. * * @return string The proxy class. */ protected static function popsProxyClass() { return __NAMESPACE__ . '\OutputEscaperProxy'; } }
namespace OutputEscaper; use Eloquent\Pops\ProxyPrimitive; /** * Wraps a primitive to escape its value for use in HTML. */ class OutputEscaperProxyPrimitive extends ProxyPrimitive { /** * Get the HTML-escaped version of this primitive. * * @return string The HTML-secaped version of this primitive. */ public function __toString() { return htmlspecialchars( strval($this->popsValue()), ENT_QUOTES, 'UTF-8' ); } }
The output escaper can now be used like so:
use OutputEscaper\OutputEscaperProxy; use Eloquent\Pops\Safe\SafeProxy; $list = new ArrayIterator( array( 'foo', 'bar', '<script>alert(document.cookie);</script>', SafeProxy::proxy('<em>ooh...</em>'), ) ); $proxy = OutputEscaperProxy::proxy($list, true); echo "<ul>\n"; foreach ($proxy as $item) { printf("<li>%s</li>\n", $item); } echo "</ul>\n";
Which would output:
<ul> <li>foo</li> <li>bar</li> <li><script>alert(document.cookie);</script></li> <li><em>ooh...</em></li> </ul>
Note that the above example should NOT be used in production. Output escaping is a complex issue that should not be taken lightly.
Excluding values from recursion
Note that in the above example, the last list item was wrapped in a Safe proxy. When Pops applies its proxies, it will skip anything marked as safe in this manner.
Calling methods with by-reference parameters
Because of PHP limitations, methods with arguments that are passed by reference must be called in a special way.
To explain futher, let's assume our class from before also has a method which accepts a reference:
class Confusion { public function butWho(&$wasPhone) { $wasPhone = 'Hello? Yes this is dog.'; } }
This method cannot be proxied normally because the $wasPhone argument is
passed by reference. The correct way to call the above butWho() method through a
Pops proxy looks like this:
use Eloquent\Pops\Proxy; $proxy = Proxy::proxy(new Confusion); $wasPhone = null; $arguments = array(&$wasPhone); $proxy->popsCall('butWho', $arguments); echo $wasPhone; // outputs 'Hello? Yes this is dog.'
Note that there must be a variable for the $wasPhone argument, and there
must be a variable for the arguments themselves. Neither can be passed
directly as a value. The arguments must also contain a reference to
$wasPhone argument.
eloquent/pops 适用场景与选型建议
eloquent/pops 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 852.9k 次下载、GitHub Stars 达 16, 最近一次更新时间为 2026 年 01 月 04 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「object」 「proxy」 「property」 「method」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 eloquent/pops 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 eloquent/pops 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 eloquent/pops 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Lazy loading for middleware and request handlers
A set of useful PHP classes.
Utility library for making class that can contain properties
Runn Me! Value Objects Library
Laravel SDK mapping data in object
Provides property information based on class documentation
统计信息
- 总下载量: 852.9k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 20
- 点击次数: 26
- 依赖项目数: 3
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-04