简体   繁体   English

PHP OOP ::在类之间传递会话密钥

[英]PHP OOP :: passing session key between classes

I am trying to work out the most appropriate design to pass a session key between classes in PHP 5.3. 我试图找出最合适的设计来在PHP 5.3中的类之间传递会话密钥。

The session key is retrieved from a 3rd-party API and my application makes various API calls that all require this session key to be passed in. 会话密钥是从第三方API检索的,我的应用程序会进行各种API调用,这些调用都需要传入此会话密钥。

I have created classes to hold related API calls egClass cart holds methods that, when called, will fire off request to the API to return data from calls such as API_GetCart(), API_AddItem() etc. 我已创建了用于保存相关API调用的类egClass cart保存方法,这些方法在调用时将触发对API的请求,以从API_GetCart(),API_AddItem()等调用返回数据。

I am storing the session key in a single cookie (the only cookie that is ever required) and need to make the value of that cookie available to pretty much all of my classes. 我将会话密钥存储在一个cookie(唯一需要的cookie)中,并且需要使该cookie的值可用于我的所有类。 I cannot use a database or $_SESSION to hold session data. 我不能使用数据库或$ _SESSION来保存会话数据。 The 3rd-party API looks after session management for things like basket contents etc. 第三方API负责管理篮子内容等会话管理。

When a user reaches my app for the very first time there will be no cookie value so I need to be able to both assign a new session key to a new cookie and also pass that value (not yet available as a cookie since we're still processing the same HTTP request) to the other classes. 当用户第一次到达我的应用程序时,将没有cookie值,因此我需要能够为新cookie分配新的会话密钥并传递该值(因为我们是仍然处理相同的HTTP请求)到其他类。

One idea I had was to create a Session class like this, and put the session grabbing/checking code in the constructor. 我的一个想法是创建一个像这样的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
    }
}

Then on all view pages I would instantiate a new instance of Session and then pass that object into each class that requires it (nearly all do), either as argument to class constructor or as method argument. 然后在所有视图页面上,我将实例化一个新的Session实例,然后将该对象传递给需要它的每个类(几乎所有这些),作为类构造函数的参数或作为方法参数。

orderSummary.php 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 

Is creating a Session class (that really only holds a single value) the best idea? 创建一个Session类(实际上只包含一个值)是最好的主意吗? Given that it may need to hold more values and perform more checking, it felt 'right' making it a class. 鉴于它可能需要持有更多的价值并进行更多的检查,因此感觉“正确”使它成为一个阶级。 In terms of passing that value to the various classes, would it be best to pass in the Session object to their constructor, eg 就将该值传递给各个类而言,最好将Session对象传递给它们的构造函数,例如

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

I'm new to OOP so some guidance would be very much appreciated. 我是OOP的新手,所以非常感谢一些指导。

You may use Factory Pattern. 您可以使用工厂模式。 Basket, Billing and Delivery objects should be created by the 3rd-party service API wrapper class: Basket,Billing和Delivery对象应由第三方服务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();

The best way to connect Basket, Billing and Delivery class with the API is storing a reference to the API class, then they can call any method of it, not just getSession(). 将Basket,Billing和Delivery类与API连接的最佳方法是存储对API类的引用,然后它们可以调用它的任何方法,而不仅仅是getSession()。

Another advantage is, that if you have an identified entity, eg a User, then the wrapper class can grant you, that there will be no double objects in the scene. 另一个优点是,如果你有一个已识别的实体,例如一个用户,那么包装类可以授予你,场景中不会有双重对象。

If the main program creates the users, there should be different objects with the same user, which is wrong: 如果主程序创建用户,则应该有相同用户的不同对象,这是错误的:

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

VS if the API wrapper creates them, the wrapper class should keep a "cache" of users, and return with the same User object for the same request: VS如果API包装器创建它们,则包装器类应该保留用户的“缓存”,并使用相同的User对象返回相同的请求:

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

(Maybe it's not a best example, if a program creates twice the same User, it means that the program has major design faulty.) (也许这不是一个最好的例子,如果一个程序创建两个相同的用户,则意味着该程序的主要设计有问题。)

UPDATE: explanation of svc class 更新: svc类的解释

The The3rdPartyServiceApiWrapper should look like this: The3rdPartyServiceApiWrapper应如下所示:

 function getSessionId() {
   return $this->sessionId;  // initialized by constructor
 } // getSessionId()

 function createBasket() {
   $basket = new Basket($this);
   return $basket;
 } // createBasket()

The Basket: 篮子:

 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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM