制作我自己的(非数据库)fetch_object 函数

2024-04-17

在 php mysql / mysqli / postgre / 等中...有 fetch_object 函数,您可以在其中获取数据行的对象。默认情况下它将返回一个对象stdClass,但您也可以为构造函数定义一个 class_name 和一个参数数组。

我想用一组简单的值做同样的事情。优选地,设置对象的属性before调用构造函数,这与数据库函数显示的行为相同。然而,这似乎不可能。

创建具有属性集的对象的唯一方法似乎是反序列化预先构造的字符串 http://www.php.net/manual/en/language.types.type-juggling.php#100460。但该示例仍然创建一个新对象,然后从未序列化的对象中设置该对象的属性以确保调用构造函数。但这意味着在设置属性之前调用构造函数。

简而言之:我想要以下内容:

array_fetch_object(array $properties, string $class_name [, array $params ])

设置属性后调用构造函数。


最后,我编写了以下类,它使用反序列化伪造的字符串来执行任务。它使用反射来确定属性的访问类型是什么以及构造函数的名称是什么(如果有)。

该类的核心是下面一行:

$object = unserialize('O:'.strlen($class_name).':"'.$class_name.'"'.substr(serialize($properties), 1));

它序列化属性数组并将序列化的重命名为所需的类名。

class ObjectFactory {

    private $properties;
    private $constructors;

    public function __construct() {
        $this->properties   = array();
        $this->constructors = array();
    }

    private function setClass($class_name) {

        $class = new ReflectionClass($class_name);
        $this->properties[$class_name] = array();

        foreach($class->getProperties() as $property) {

            $name     = $property->getName();
            $modifier = $property->getModifiers();

            if($modifier & ReflectionProperty::IS_STATIC) {
                continue;
            } else if($modifier & ReflectionProperty::IS_PUBLIC) {
                $this->properties[$class_name][$name] = $name;
            } else if($modifier & ReflectionProperty::IS_PROTECTED) {
                $this->properties[$class_name][$name] = "\0*\0".$name; // prefix * with \0's unserializes to protected property
            } else if($modifier & ReflectionProperty::IS_PRIVATE) {
                $this->properties[$class_name][$name] = "\0".$class_name."\0".$name; // prefix class_name with \0's unserializes to private property
            }
        }

        if($constructor = $class->getConstructor()) {
            $this->constructors[$class_name] = $constructor->getName();
        }
    }

    private function hasClassSet($class_name) {

        return array_key_exists($class_name, $this->properties);
    }

    private function hasClassProperty($class_name, $property_name) {

        if(!$this->hasClassSet($class_name))
            $this->setClass($class_name);

        return array_key_exists($property_name, $this->properties[$class_name]);
    }

    private function getClassProperty($class_name, $property_name) {

        if(!$this->hasClassProperty($class_name, $property_name))
            return false;

        return $this->properties[$class_name][$property_name];
    }

    private function hasClassConstructor($class_name) {

        if(!$this->hasClassSet($class_name))
            $this->setClass($class_name);

        return $this->constructors[$class_name] !== false;
    }

    private function getClassConstructor($class_name) {

        if(!$this->hasClassConstructor($class_name))
            return false;

        return $this->constructors[$class_name];
    }

    public function fetch_object(array $assoc, $class_name = 'stdClass', array $params = array()) {

        $properties = array();

        foreach($assoc as $key => $value) {
            if($property = $this->getClassProperty($class_name, $key)) {
                $properties[$property] = $value;
            }
        }

        $object = unserialize('O:'.strlen($class_name).':"'.$class_name.'"'.substr(serialize($properties), 1));

        if($constructor = $this->getClassConstructor($class_name)) {
            call_user_func_array(array($object, $constructor), $params);
        }

        return $object;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

制作我自己的(非数据库)fetch_object 函数 的相关文章

  • 获取今天的科普特日期

    我正在寻找获取今天的科普特日期与任何代码类型类似php or javascript在我的网站标题中显示科普特日期 我需要阿拉伯语或英语版本 我试图找到它 但没有找到类似的英文内容 参考 http www copticchurch net e
  • 如何更改codeception phpbrowser/mink超时

    我正在尝试使用代码接收创建测试 以检查页面在高负载的情况下是否正常工作 不幸的是 如果页面负载非常高并且测试开始 我会收到这样的错误 Codeception Exception ModuleConfig Codeception Util M
  • 将 OAuth WRAP 访问令牌直接保存在客户端计算机上的 cookie 中吗?

    我计划建立一个可以访问 oauth 包装框架的网站 我正在考虑将访问令牌按原样存储在客户端计算机上 我不想在服务器上维护临时令牌等数据库 我应该做吗 或者我应该加密它 首先 为什么他们不使用 OAuth 2 0 您可以将 OAuth 凭据存
  • 如何在 CakePHP 中“验证”人名?

    我有一个 PHP 脚本 应该检查 有效 的人名 但最近破解了带有空格的名称 因此我们向验证器添加了空格 除了这样做之外 有没有办法向 CakePHP 的验证器添加黑名单以阻止所有 无效 字符 而不是允许 有效 字符 注意 我 通常 知道如何
  • 在laravel中组合两个不同的无关系数据库表查询进行分页

    我的数据库中有两个不相关的表 我需要将它们合并 以便我可以将其放在我的搜索视图中 但我不知道是否可能 这是我的代码 这news and season表不相关 但它们具有相似的列 我试图将其放入一个对象中以便于分页 是否可以 search r
  • 在 Laravel 中的编辑表单上获取选定选项

    我的网站订单有一个可编辑的表单 并且有以下字段 User quantity note status 我在此表单中还有其他选项 但只有这些字段对我来说很重要 以便能够获取默认值 例如 我希望能够查看用户默认订购的数量 然后我可以更改它或保留它
  • Zend Framework 中的动态默认模块

    有谁知道在 Zend Framework 中动态设置默认模块并且不会遇到命名空间问题的方法 例如 我想要做的是有一个允许加载的模块表 其中一个设置为默认模块 例如 我可能有 admin blog calendar 作为可以加载的模块 如果我
  • div 中的文本字符有限,添加“阅读更多”链接并在单击链接时显示所有字符

    我有一个 div 里面有文本 使用 PHP 和 MySQL 显示 结构如下 div class description p Here is a lot of text p div 我想在 p 标签内的文本超过 100 个字符时显示 阅读更多
  • PHP 的脚手架 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 PHP 中有什么东西可以像 Rails 一样创建基本的脚手架吗 编辑 我需要一些东西来快速原型化 一些框架比如Symfony http www sym
  • 纯基于网络的版本控制系统

    我的托管服务当前不允许在其服务器上运行 允许 svn git cvs 我真的希望能够将我的开发计算机上的当前源代码与我的生产服务器 同步 我正在寻找一个纯php python ruby版本控制系统 不只是一个client对于版本控制系统 不
  • yii2 中的自动完成

    在 Yii2 中 我希望当用户开始输入时 我的输入字段之一能够自动完成 下面是我的代码 它使用Jui Autocomplete 这是行不通的 当我打印我的数组时 我就像 Array 1 gt abc 2 gt xyz 4 gt pqr
  • PHP-docker容器中的环境变量

    我想在我的 docker 容器中显示一个环境变量 PHP 脚本如下所示 我使用 OpenShift 来启动容器 PHP 容器显示 env is 现在我更改容器的 dc 配置 oc env dc envar USER Pieter deplo
  • PHP 脚本不断执行 mmap/munmap

    我的 PHP 脚本包含一个循环 它只不过是回显和取消引用指针 如 tab othertab i gt 中的内容 直到昨天 这个脚本开始变得非常慢 比以前慢了 50 倍 之前 它一直运行良好 使用 strace 后 我发现 90 的情况下 脚
  • OnClick 事件中的 finish() 如何工作?

    我有一个Activity一键退出Activity 通过layout xml我必须设置OnClick事件至cmd exit调用 this finish 效果很好 public void cmd exit View editLayout thi
  • Paypal 将钱从一个帐户转移到另一个帐户

    我知道这个建议如何汇款至任何 PayPal 账户 https stackoverflow com questions 1559808 paypal api send money to any paypal account但到目前为止我所尝试
  • 在 PHP 中接受带有小数点和千位分隔符的国际数字

    对于用户可以输入能量值来计算相应费用的在线计算器 我需要 PHP 脚本来接受各种用户输入 200 万又四分之一焦耳 的值可以输入为 2000000 25 默认表示法 2 000 000 25 带千位分隔符 2000000 25 逗号作为小数
  • PHP 共享标头而不使用服务器端脚本?

    到目前为止我总是通过 PHP 解决简单的问题 您有一个包含页眉 菜单 页脚和内容字段的网站 每个页面的页眉 菜单和页脚通常是相同的 在没有 PHP 或任何其他服务器端语言的情况下 如何使页眉 菜单和页脚数据仅存在于一个文件中 例如 您不会有
  • 使用 MYSQL 将 h:mm pm/am 时间格式插入数据库

    我正在尝试将以 h mm am pm 格式写入的时间插入到存储为标准 DATETIME 格式 hh mm ss 的数据库中 但我不知道如何将发布的时间转换为标准格式所以数据库会接受它 这是我到目前为止一直在尝试的 title POST in
  • 禁用 WooCommerce 手动/编辑订单的电子邮件通知

    需要 WooCommerce 专业知识 我需要禁用手动创建的订单的电子邮件通知 我必须使用处理状态 由于处理订单状态的自定义挂钩 我无法创建自定义状态 理想情况下 手动订单页面中可以勾选一个复选框 勾选后 它将禁止在每种状态下向客户发送电子
  • 通过 Sparkpost 发送 iCal 邀请

    我正在尝试使用 SparkPost 通过电子邮件以附件形式发送日历邀请 但收到电子邮件后邀请不会打开 我使用两个文件 calendarinvite php 来创建邀请 使用 Sendemail php 来发送电子邮件 calendarinv

随机推荐