如何跨PHP类全局共享消息?

6xfqseft  于 2023-03-16  发布在  PHP
关注(0)|答案(1)|浏览(171)

我正在构建一个小框架来使自己回到PHPOOP的速度上来。我希望能够验证表单,并且需要一种跨类检查错误包的方法。
一开始我试着把MyApp类注入到Validator类中,但是会有几个子类,我可以看到这很快就会变得很糟糕,所以我开始尝试Base类,它的方法和属性可以在多个类之间共享,所以如果有错误,Base类可以设置它,然后其他类可以检索它。
我已经尝试了一个简单的实现,虽然我没有收到任何PHP错误,但我也无法将errorValidator类传递回MyApp类,以便将其打印在Web页面上。
所以我的问题是:为什么Validator中的$this->setError($key, $key . ' is required')没有传递回Base,或者如果传递回Base,为什么我无法获取MyApp中的值并将其打印在页面上?
或者,对于这种场景,是否有更好的全局处理消息的方法?

基类

<?php

namespace MyApp;

class Base
{
    public array $errors = [];

    public function setError($key, $message): void
    {
        $this->errors[$key] = $message;
    }

    public function errors(): array
    {
        return $this->errors;
    }
}

MyApp类(面向公众)

<?php

namespace MyApp;

class MyApp extends Base
{
    public Validator $validator;

    public function __construct()
    {
        $this->validator = new Validator;
    }

    public function text($key): string
    {
        return '<input type="text" name="' . $key . '" value="' . ($_POST[$key] ?? '') . '">';
    }

    public function request($key): string
    {
        return $this->validator->request($key);
    }
}

验证器类

<?php

namespace MyApp;

class Validator extends Base
{
    public function request($key): string
    {
        if (empty($_POST[$key])) {
            $this->setError($key, $key . ' is required');
        }

        return $_POST[$key];
    }
}

Web表单

<?php

require 'vendor/autoload.php';
$app = new MyApp\MyApp;

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $name = $app->request('name');

    var_dump($app->errors());
}
?>
<form action="/" method="post">
    <?= $app->text('name'); ?>
    <button type="submit">Submit</button>
</form>
xwbd5t1u

xwbd5t1u1#

事实上,你的两个类共享相同的Base-Class并不意味着它们之间共享任何运行时数据,这是两个不同的Instances的东西,扩展了Base。
你能做的就是把你的$errors设置为静态的。静态属性在所有示例中共享。然后你可以通过它的类型名而不是任何特定的示例来引用它:

class Base
{
public static array $errors = [];

//function now could be static as well to outline that is has no relation to the instance itself.
public static function setError($key, $message): void
{
    //could also use self::errors here.
    Base::errors[$key] = $message;
}

public static function errors(): array
{
    //could also use self::errors here.
    return Base::errors;
}
}

从base的任何子元素中,您现在可以使用parent::errors()Base::errors()访问完全相同的数组。
但是请注意,共享属性accross threads会由于并发访问和/或修改而导致问题。
这里还有一个问题,如果您真的想在每个对象中共享错误-或者如果您只是需要基于用户会话的错误?
对于后一种情况,只需查看$_SESSION,它是一个数组,可以包含您想要的任何内容,可以从同一会话中的任何位置访问。

相关问题