So I have a class I'm working on to manage PHP sessions, here's the class:
class SessionManagement {
public static function sessionStarted() {
if(session_id() == '') {
return false;
} else {
return true;
}
}
public static function sessionExists($session) {
if(sessionStarted() == false) {
session_start();
}
if(isset($_SESSION[$session])) {
return true;
} else {
return false;
}
}
public static function setSession($session, $value) {
if(sessionStarted() != true) {
session_start();
}
$_SESSION[$session] = $value;
if(sessionExists($session) == false) {
throw new Exception('Unable to Create Session');
}
}
public static function getSession($session) {
if(isset($_SESSION[$session])) {
return $_SESSION[$session];
} else {
throw new Exception('Session Does Not Exist');
}
}
}
Now trying this...
try {
SessionManagement::setSession('Foo', 'Bar');
echo SessionManagement::sessionStarted();
echo SessionManagement::getSession('Foo');
echo SessionManagement::sessionExists('Foo');
} catch(Exception $e) {
echo $e->getMessage();
}
...produces no output...I'm not sure where we're breaking here...any helpful eyes is greatly appreciated...
Unlike other OO languages, like C++, in your class PHP needs to know that the static methods called are from this object. For an instantiated class, that would be through $this, and in your case, static methods, this is done via self:
class SessionManagement {
public static function sessionStarted() {
if(session_id() == '') {
return false;
} else {
return true;
}
}
public static function sessionExists($session) {
if(self::sessionStarted() == false) {
session_start();
}
if(isset($_SESSION[$session])) {
return true;
} else {
return false;
}
}
public static function setSession($session, $value) {
if(self::sessionStarted() != true) {
session_start();
}
$_SESSION[$session] = $value;
if(self::sessionExists($session) == false) {
throw new Exception('Unable to Create Session');
}
}
public static function getSession($session) {
if(isset($_SESSION[$session])) {
return $_SESSION[$session];
} else {
throw new Exception('Session Does Not Exist');
}
}
}
Prepending self:: to all internal calls to the SessionManagement static methods should solve your problem.
Related
I wrote a static Session class that can obviously 'set, get, start but does not destroy' temp user sessions, meaning i have to start a session on each page to be able to destroy it, which make no sense in programming standards.any better way to this approach?
class sessionWrapper {
private static $_sessionStarted = false;
public static function start() {
if(self::$_sessionStarted == false) {
session_start();
self::$_sessionStarted = true;
}
}
public static function set($key, $value) {
$_SESSION[$key] = $value;
}
public static function get($key) {
if(isset($_SESSION[$key])) {
return $_SESSION[$key];
} else {
return false;
}
}
public static function destroy() {
if(self::$_sessionStarted == true) {
session_destroy();
header('Location: $url');
}
}
}
I have a shopping cart object that implements serializable, and it works fine on my localhost, but when I upload it to the live server it stops working correctly.
When I add a product to the shopping cart and print_r($_SESSION) I can see the products have been added successfully, but when I refresh the page they disappear. This only happens with objects that implement serializable. These same objects work perfectly on my localhost, which has IDENTICAL code, and it's driving me insane.
Could it be a difference in session handling between php version 5.5 and 5.6?
I am using spl_autoload_register to load my classes if that helps at all (none of them appear in the session as incomplete_class or anything like that).
I also noticed that the session save path is blank on the live version, but is set on my localhost - but the rest of the session functions perfectly - it's only when it contains serializable classes that everything disappears.
Please help before I murder someone...
OK here's the code:
shopping cart class:
class shoppingCart implements Serializable
{
private $products, $error;
function __construct()
{
}
function addProduct($productCode, $quantity = 1)
{
include_once ('include/requests.php');
$productInfo = requestPostData('getProductList');
if (in_array(strtoupper($productCode), $productInfo['results']) == true)
{
if (isset($this->products[strtoupper($productCode)]))
{
$this->products[strtoupper($productCode)] = $this->products[strtoupper($productCode)] + $quantity;
return true;
}
else
{
$this->products[strtoupper($productCode)] = $quantity;
return true;
}
}
else
{
$this->error = 'Product '.$productCode.' could not be found.';
}
}
function editProduct($productCode, $quantity)
{
if (isset($this->products[strtoupper($productCode)]))
{
$this->products[strtoupper($productCode)] = $quantity;
}
}
function removeProduct($productCode)
{
if (isset($this->products[strtoupper($productCode)]))
{
unset($this->products[strtoupper($productCode)]);
}
}
public function getProducts()
{
if (count($this->products) >= 1)
{
return $this->products;
}
else
{
return false;
}
}
public function isInCart($productCode)
{
if (isset($this->products[strtoupper($productCode)]))
{
return true;
}
else
{
return false;
}
}
public function getQuantity($productCode)
{
if (isset($this->products[strtoupper($productCode)]))
{
return $this->products[strtoupper($productCode)];
}
else
{
return 0;
}
}
public function getError()
{
$error = $this->error;
return $error;
}
public function resetError()
{
$this->error = '';
}
public function serialize()
{
$dataArray = array('products' => $this->products, 'error' => $this->error);
return serialize($dataArray);
}
public function unserialize($data)
{
$dataArray = unserialize($data);
$this->products = $dataArray['products'];
$this->error = $dataArray['error'];
}
}
And the code on the page:
if (session_status() !== PHP_SESSION_ACTIVE)
{
session_start();
}
if (!isset($_SESSION['shoppingCart']))
{
$_SESSION['shoppingCart'] = new shoppingCart;
}
if (isset($_POST['cart__add_to_cart']))
{
if (isset($_POST['cart__quantity']))
{
if ($_SESSION['shoppingCart']->addProduct($_POST['cart__add_to_cart'], $_POST['cart__quantity']))
{
header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
}
}
else
{
if ($_SESSION['shoppingCart']->addProduct($_POST['cart__add_to_cart']))
{
header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
}
}
}
If I print_r($_SESSION) right at the bottom of the page after a product has been added then it appears in the session as it should... But as soon as I refresh it disappears :'(
I have a system that was designed to do a kind of cascading - get the sequence of methods called upon success of the previous condition.
The example is the below code, which I presume it's not a best practice for doing this, so would be great if I could get some suggestions to refactor this, probably using a design pattern or a different than this system.
<?php
class Model
{
public function isOk()
{
return true;
}
}
class OtherClass
{
public function isOk()
{
return true;
}
}
class AnotherClass
{
public function verifies()
{
return true;
}
}
class Sequence
{
public function fire()
{
$model = new Model();
if($model->isOk()) {
$otherclass = new OtherClass();
if($otherclass->isOk()) {
$anotherclass = new AnotherClass();
if($anotherclass->verifies()) {
echo "We're done with the sequence.";
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
}
$sequence = new Sequence();
echo $sequence->fire();
?>
I would avoid deep nesting of if/else statements to enhance the readability. One way is to use early return:
class Test1
{
public function isOk()
{
echo 'Test1';
return true;
}
}
class Test2
{
public function isOk()
{
echo 'Test2';
return true;
}
}
class Sequence
{
public function fire()
{
$test1 = new Test1();
if (!$test1->isOk()) {
return false;
}
$test2 = new Test2();
if (!$test2->isOk()) {
return false;
}
echo "We're done with the sequence.";
return true;
}
}
If you need it more dynamically you could use call_user_func or call_user_func_array.
class Sequence
{
protected $sequence = array(
array('Test1', 'isOk'),
array('Test2', 'isOk'),
);
public function fire()
{
foreach ($this->sequence as $callback) {
if (!call_user_func(array(new $callback[0], $callback[1]))) {
return false;
}
}
echo "We're done with the sequence.";
return true;
}
}
I have a class like this:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
class api {
function __construct($_GET) {
if ($_GET['method'] == "add") {
$this->add();
}
else if ($_GET['method'] == "subtract") {
$this->subtract();
}
}
function add() {
return "Adding!";
}
function subtract() {
return "Subtracting!";
}
}
$api = new api($_GET);
echo $api;
?>
When I send a URL from the browser of : test.php?method=add
I’m not getting any output or error messages. What I am missing?
Your construct function is not returning anything, only your other functions. Try this.
Class api {
function __construct($_GET) {
if ($_GET['method'] == "add") {
$this->message = $this->add();
}
else if ($_GET['method'] == "subtract") {
$this->message = $this->subtract();
}
}
function add() {
return "Adding!";
}
function subtract() {
return "Subtracting!";
}
}
$api = new api($_GET);
echo $api->message;
Change your contructor to this...
function __construct() {
if(isset($_GET)){
if($_GET['method']== "add") {
$this->add();
}
else if($_GET['method'] == "subtract"){
$this->subtract();
}}
}
You don't have to pass $_GET into the construct, as its a super global and is available everywhere, all the time
Try this
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
class api {
function __construct() {
if ($_GET['method'] == "add") {
return $this->add();
}
else if ($_GET['method'] == "subtract") {
return $this->subtract();
}
}
function add() {
return "Adding!";
}
function subtract() {
return "Subtracting!";
}
}
$api = new api();
echo $api->__construct();
?>
__construct() is the class method so in order to get the returned value from this method you have to use it this way $api->__construct()
How can I check if my object has returned false or not? I have the following class:
class Test {
public function __construct($number) {
if($number != '1') {
return FALSE;
}
}
}
I've tried:
$x = new Test('1');
$x = new Test('2');
But when I var_dump($x), I get the same results. I want to do a:
if(! $x = new Test('1')) {
header("location: xxx...");
}
You cannot return anything from a constructor. If you want the construction of an object to fail, you'll have to throw an Exception.
As deceze said, constructors cannot return a value. You could create a factory method that returns false, like:
class Test
{
public function __construct($number) {
...
}
public function factory($number) {
return ($number != '1') ? false : new self($number);
}
}
$x = Test::factory('1');
if (!$x) {
header('Location: ...');
}
But I would use exceptions instead
class Test
{
public function __construct($number) {
if ($number != '1') {
throw new IllegalArgumentException('Number must be "1"');
}
...
}
}
try {
$x = new Test('1');
} catch (Exception $e) {
header('Location: ...');
}