【问题标题】:PHP OOP :: passing session key between classesPHP OOP :: 在类之间传递会话密钥
【发布时间】:2011-06-03 06:53:41
【问题描述】:

我正在尝试制定最合适的设计来在 PHP 5.3 中的类之间传递会话密钥。

会话密钥是从第 3 方 API 检索的,我的应用程序进行了各种 API 调用,所有这些调用都需要传入此会话密钥。

我创建了类来保存相关的 API 调用,例如,类购物车保存的方法在调用时会触发对 API 的请求,以从 API_GetCart()、API_AddItem() 等调用返回数据。

我将会话密钥存储在单个 cookie(唯一需要的 cookie)中,并且需要使该 cookie 的值可用于我的几乎所有类。我不能使用数据库或 $_SESSION 来保存会话数据。第 3 方 API 负责对购物篮内容等进行会话管理。

当用户第一次访问我的应用程序时,将没有 cookie 值,因此我需要能够为新 cookie 分配一个新的会话密钥并传递该值(因为它还不能作为 cookie 使用我们仍在处理相同的 HTTP 请求)到其他类。

我的一个想法是创建一个这样的 Session 类,并将会话抓取/检查代码放在构造函数中。

class Session {
    public $sk;
    function __construct() {
        //code to check if user has sessionkey (sk) in cookie
        //if not, grab new sessionkey from 3rd party API and assign to new cookie
        // $sk = 'abcde12345'; //example $sk value
    }
}

然后在所有视图页面上,我将实例化一个新的 Session 实例,然后将该对象传递给每个需要它的类(几乎都这样做),作为类构造函数的参数或作为方法参数。

orderSummary.php

$s = new Session;

//$s currently would only hold one variable, $sk = "abcde12345"
//but in the future may hold more info or perform more work

// what is best approach to making the sessionkey 
// available to all classes? arg to constructor or method... or neither :)

$basket = new Basket;
$baskSumm = $basket->getBasketSummary();

$billing = new Billing;
$billSumm = $billing->getBillingSummary();

$delivery = new Delivery;
$delSumm = $delivery->getDeliverySummary();

//code to render as HTML the customer's basket details
//as well as their billing and delivery details 

创建一个 Session 类(实际上只包含一个值)是最好的主意吗?鉴于它可能需要保存更多值并执行更多检查,因此将其作为一个类感觉“正确”。就将该值传递给各个类而言,最好将 Session 对象传递给它们的构造函数,例如

$se = new Session;
$basket = new Basket($se);
$baskSumm = $basket->getBasketSummary();

我是 OOP 的新手,因此非常感谢一些指导。

【问题讨论】:

    标签: php oop class sessionid


    【解决方案1】:

    您可以使用工厂模式。 Basket、Billing 和 Delivery 对象应由第 3 方服务 API 包装类创建:

    $svc = new The3rdPartyServiceApiWrapper();
    $svc->init();  // connect, get session etc.
    if ($svc->fail()) die("halp! error here!");
    
    $basket = $svc->createBasket();
    $baskSumm = $basket->getBasketSummary();
    
    $billing = $svc->createBilling();
    $billSumm = $billing->getBillingSummary();
    
    $delivery = $svc->createDelivery();
    $delSumm = $delivery->getDeliverySummary();
    

    将 Basket、Billing 和 Delivery 类与 API 连接的最佳方式是存储对 API 类的引用,然后他们可以调用它的任何方法,而不仅仅是 getSession()。

    另一个优点是,如果您有一个已识别的实体,例如一个用户,然后包装类可以授予您,场景中不会有双重对象。

    如果主程序创建用户,同一个用户应该有不同的对象,这是错误的:

    $user1 = new User("fred12");
    $user2 = new User("fred12");
    

    如果 API 包装器创建它们,包装器类应该保留用户的“缓存”,并为相同的请求返回相同的用户对象:

    $user1 = $svc->createUser("fred12");
    $user2 = $svc->createUser("fred12");  // $user2 will be the same object
    

    (也许这不是一个最好的例子,如果一个程序创建了两次相同的用户,这意味着该程序存在重大设计错误。)

    更新: svc 类的解释

    The3rdPartyServiceApiWrapper 应该如下所示:

     function getSessionId() {
       return $this->sessionId;  // initialized by constructor
     } // getSessionId()
    
     function createBasket() {
       $basket = new Basket($this);
       return $basket;
     } // createBasket()
    

    篮子:

     function Basket($s) {  // constructor of Basket class
    
       $this->svc = $s;
    
       //... the rest part of constructor
    
     } // Basket() constructor
    
    function doSomethingUseful() {
    
      // if you wanna use the session:
      $sess = $this->svc->getSessionId();
      echo("doing useful with session $session");
    
      // you may access other api functions, I don't know what functions they provide
      $this->svc->closeSession();
    
    } // doSomethingUseful()
    

    【讨论】:

    • 感谢您的回复。所以我仍然会保留我的 Basket 对象及其所有方法,但只需通过包装类 The3rdPartyServiceApiWrapper 实例化它?这样做,我是否正确地认为 Basket 对象的 getBasketSummary() 方法中,我可以引用作为 The3rdPartyServiceApiWrapper 类的成员变量的 sessionkey?对于每个查看页面请求,都会创建一个新的 The3rdPartyServiceApiWrapper 对象,其中包含“必须具有”的变量,例如会话密钥,以及对创建的新对象的引用,例如 Basket、Summary 等?
    • 查看更新...无论如何,必须为每个页面请求创建 The3rdPartyServiceApiWrapper,这就是 PHP 的工作原理。 AFAIK 没有办法使用后台服务类,比如在 Java 中。不过这样就好了。
    猜你喜欢
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    相关资源
    最近更新 更多