在Laminas Session中初始化变量的错误

huangapple go评论70阅读模式
英文:

Bug to initialize a variable in the Laminas Session

问题

我在我的代码中遇到了一个奇怪的错误。我在控制器中的会话中初始化了一个变量。但当我在视图中检索数据时,该变量等于null。

控制器的代码:

$session = new Container("example");
...
$session["data"] = "test";
//这一行是我找到的唯一数据被初始化的方法
$session["data"] = $session["data"];
...
return new ViewModel(array(
    "session" => $session
));

视图的代码:

$data = $this->session["data"];

我必须添加下面这行代码才能使我的值被初始化:

$session["data"] = $session["data"];

如果没有这行代码,该变量将等于NULL。

为什么需要这样做?为什么变量不会在没有它的情况下初始化?

谢谢你的帮助。

英文:

I had a curious bug that happened in my code. I initialize a variable in the session in the controller. But when I retrieve the data in the view, the variable is equal to null.

The code of the Controller:

$session = new Container("exemple");
...
$session["data"] = "test";
//This line is the only way I found for the data to be initialized
$session["data"] = $session["data"];
...
return new ViewModel(array(
    "session" => $session
));

The code of the View:

$data = $this->session["data"];

I have to add the line below for my value to be initialized:

$session["data"] = $session["data"];

Without this line the variable is equal to NULL.

Why is it necessary to do this? Why is the variable not initialized without it?

Thanks for your help.

答案1

得分: 1

以下是翻译好的部分:

"使用 Laminas 控制器中的会话,您需要执行比仅仅初始化一个会话容器更多的步骤,而没有提供有关此容器应如何工作的详细信息。

官方 Laminas 文档中所述,您需要定义三个内容:

  • 会话容器的名称
  • 会话存储处理程序
  • 会话的可选配置

如文档中所述,使用基于反射的方法可能是最简单的方法。您需要在 config/autoload/global.config.php 中定义会话设置。

return [
    'session_containers' => [
        Laminas\Session\Container::class,
    ],
    'session_storage' => [
        'type' => Laminas\Session\Storage\SessionArrayStorage::class,
    ],
    'session_config'  => [
        'gc_maxlifetime' => 7200,
        // …
    ],
    // …
];

从现在开始,您可以在控制器中使用会话。考虑以下代码示例。

<?php

declare(strict_types=1);

namespace Marcel\Controller;

use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Session\Container as SessionContainer;

class YourController extends AbstractActionController
{
    public function __construct(
        protected readonly SessionContainer $sessionContainer
    ) {}
}

此控制器具有一个构造方法,它注入了会话容器。一旦注入,您就可以在控制器中使用会话。如上所述,会话容器将通过反射的方法注入。您需要在模块配置中定义控制器工厂。

<?php

declare(strict_types=1);

namespace Marcel;

use Laminas\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory;

return [
    'controllers' => [
        'factories' => [
            // 添加这行
            Controller\YourController::class => ReflectionBasedAbstractFactory::class,
        ],
    ],
    // …
];

从现在开始,您的控制器将使用在全局配置中定义的有效会话容器进行初始化。您可以如下使用它...

// 设置会话数据
public function indexAction()
{
    $this->sessionContainer->data = 'Some random data';

    return [];
}

// 读取会话数据
public function addAction()
{
    return [
        'data' => $this->sessionContainer->data ?? null,
    ];
}

在视图中,您需要使用定义的变量 data 的名称,而不是会话容器本身。"

英文:

For using sessions in a Laminas controller, you have to do a few steps more than just initializing a session container without any detailed information about how this container should work.

As written in the official laminas documentation you have to define three things:

  • a name for the session container
  • a session storage handler
  • an optional configuration for the session

As mentioned in the documentation using the reflection based approach might be the easiest approach. You have to define the session settings in config/autoload/global.config.php.

return [
    &#39;session_containers&#39; =&gt; [
        Laminas\Session\Container::class,
    ],
    &#39;session_storage&#39; =&gt; [
        &#39;type&#39; =&gt; Laminas\Session\Storage\SessionArrayStorage::class,
    ],
    &#39;session_config&#39;  =&gt; [
        &#39;gc_maxlifetime&#39; =&gt; 7200,
        // …
    ],
    // …
];

From now on you 're able to use the session in a controller. Think of something like the following code.

&lt;?php

declare(strict_types=1);

namespace Marcel\Controller;

use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Session\Container as SessionContainer;

class YourController extends AbstractActionController
{
    public function __construct(
        protected readonly SessionContainer $sessionContainer
    ) {}
}

This controller has a constructor method, that injects the session container. Once injected, you can use the session in your controller. As written above, the session container will be injected via reflection based approach. You have to define a controller factory in your module config.

&lt;?php

declare(strict_types=1);

namespace Marcel;

use Laminas\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory;

return [
    &#39;controllers&#39; =&gt; [
        &#39;factories&#39; =&gt; [
            // Add this line
            Controller\YourController::class =&gt; ReflectionBasedAbstractFactory::class,
        ],
    ],
    // …
];

From now on your controller will be initialized with a valid session container as you have it defined in your global config. You can use it as follows ...

// setting session data
public function indexAction()
{
    $this-&gt;sessionContainer-&gt;data = &#39;Some random data&#39;;

    return [];
}

// reading session data
public function addAction()
{
    return [
        &#39;data&#39; =&gt; $this-&gt;sessionContainer-&gt;data ?? null,
    ];
}

In your view you have to use the name of the defined variable data and not the session container itself.

huangapple
  • 本文由 发表于 2023年3月3日 21:03:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75627421.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定