How do I fix my illegal offset? - php

I've been trying to make this code work, but (with my small knowledge of coding) I can't seem to. Any ideas on how to do this?
The error is as follows:
"Warning: Illegal offset type in isset or empty in C:\UwAmp\www\undersokning\classes\Session.php on line 4"
<?php
class Session {
public static function exists($name) {
return (isset($_SESSION[$name])) ? true : false;
}
public static function put($name, $value) {
return $_SESSION[$name] = $value;
}
public static function get($name) {
return $_SESSION[$name];
}
public static function delete($name) {
if(self::exists($name)) {
unset($_SESSION[$name]);
}
}
}

Related

PHP 5.6: ArrayAccess: Function isset calls offsetGet and causes undefined index notice

I wrote simple PHP class that implements ArrayAccess Interface:
class MyArray implements ArrayAccess
{
public $value;
public function __construct($value = null)
{
$this->value = $value;
}
public function &offsetGet($offset)
{
var_dump(__METHOD__);
if (!isset($this->value[$offset])) {
throw new Exception('Undefined index: ' . $offset);
}
return $this->value[$offset];
}
public function offsetExists($offset)
{
var_dump(__METHOD__);
return isset($this->value[$offset]);
}
public function offsetSet($offset, $value)
{
var_dump(__METHOD__);
$this->value[$offset] = $value;
}
public function offsetUnset($offset)
{
var_dump(__METHOD__);
$this->value[$offset] = null;
}
}
It works normally in PHP 7, but the problem in PHP 5.6 and HHVM.
If I call function isset() on undefined index, the PHP will call offsetGet() instead of offsetExists() which will cause Undefined index notice.
In PHP 7, it calls offsetGet() only if offsetExists() returns true, so there is no error.
I think that this is related to PHP bug 62059.
The code is avalible at 3V4L, so you can see what is wrong. I added few more debug calls and throw exception if index is undefined because notices aren't shown in 3V4L:
https://3v4l.org/7C2Fs
There shouldn't be any notice otherwise PHPUnit tests will fail.
How can I fix this error?
It looks like this is a PHP bug in old versions of PHP and HHVM. Because PHP 5.6 is not supported anymore, this bug will not be fixed.
Quick fix is to add additional check in method offsetGet() and return null if index is undefined:
class MyArray implements ArrayAccess
{
public $value;
public function __construct($value = null)
{
$this->value = $value;
}
public function &offsetGet($offset)
{
if (!isset($this->value[$offset])) {
$this->value[$offset] = null;
}
return $this->value[$offset];
}
public function offsetExists($offset)
{
return isset($this->value[$offset]);
}
public function offsetSet($offset, $value)
{
$this->value[$offset] = $value;
}
public function offsetUnset($offset)
{
$this->value[$offset] = null;
}
}
See code at 3V4L and zerkms's comments (first, second, third).

Can't use function return value in write context

I have this simple session class
class Session
{
public static function init() {
#session_start();
}
public static function set($key, $value) {
$_SESSION[$key] = $value;
}
public static function get($key) {
if (isset($_SESSION[$key]))
return $_SESSION[$key];
}
public static function destroy() {
unset($_SESSION);
session_destroy();
}
}
In my other class I have
public function verifyFormToken($form)
{
// check if a session is started and a token is transmitted, if not return an error
if(!isset(Session::get($form.'_token'))){
return false;
}
// check if the form is sent with token in it
if(!isset($data['token'])) {
return false;
}
// compare the tokens against each other if they are still the same
if (Session::get($form.'_token') !== $data['token']) {
return false;
}
return true;
}
I can set a session no problem but when I come to get it using verifyFormToken(), i get this error message
Can't use function return value in write context
which points to this line
if(!isset(Session::get($form.'_token'))){
you will have to define a variable as pass that to isset:
$token = Session::get($form.'_token');
if ($token !== NULL) { ... }
or as you are using isset in your get method just do:
if (Session::get($form.'_token') !== NULL) { ... }
EDIT**
In this instance this would be fine, as session token will never be null, but as a session controller, a value may be set as NULL on purpose, or may not be set, so your get method needs to return a unique value to determine whether its set or not. i.e.
define('MY_SESSION_NOT_SET',md5('value_not_set'));
class Session
{
public static function init() {
#session_start();
}
public static function set($key, $value) {
$_SESSION[$key] = $value;
}
public static function get($key) {
if (isset($_SESSION[$key]))
return $_SESSION[$key];
else
return MY_SESSION_NOT_SET;
}
public static function destroy() {
unset($_SESSION);
session_destroy();
}
}
if (Session::get($form.'_token') === MY_SESSION_NOT_SET) { ... }
something like that would be more beneficial.

Wordpress screwing up PHP Session and form validation token not matching

For some reason when it generates a token it stores another token in the session and it is a completely random token.
Here is my code for the Token class -
class Token {
protected static $token;
public static function generate() {
if(!self::$token){
self::$token = md5(uniqid());
}
return Session::put(Config::get('session/token_name'), self::$token);
}
public static function check($token) {
$tokenName = Config::get('session/token_name');
if(Session::exists($tokenName) && $token === Session::get($tokenName)) {
Session::delete($tokenName);
return true;
}
return false;
}
}
And here is my code from my Session class -
class Session {
public static function exists($name) {
return (isset($_SESSION[$name])) ? true : false;
}
public static function get($name) {
return $_SESSION[$name];
}
public static function put($name, $value) {
return $_SESSION[$name] = $value;
}
public static function delete($name) {
if(self::exists($name)) {
unset($_SESSION[$name]);
}
}
public static function flash($name, $string = null) {
if(self::exists($name)) {
$session = self::get($name);
self::delete($name);
return $session;
} else if ($string) {
self::put($name, $string);
}
}
}
Config::get('session/token_name') just returns 'token'
No where else am I generating a new token, and it wouldn't matter anyways as it will just return one token because of the static variable.
Why is WordPress doing this?
Please help I have been trying to get this to work for over 10 straight hours!
For the generate function -
public static function generate() {
if(!Session::get(Config::get('session/token_name'))){
return Session::put(Config::get('session/token_name'), md5(mt_rand()));
}
else{
return Session::put(Config::get('session/token_name'), Session::get(Config::get('session/token_name')));
}
}
This ensures that you only create one for each session.

Simple ORM Structure Codeigniter

This is my code:
<?php
class VortexORM {
private static $orm = null;
public function __get($name) {
return $this->$name;
}
public function __set($name, $value) {
$this->$name = $value;
}
public static function getInstance() {
if (VortexORM::$orm == null)
VortexORM::$orm = new VortexORM();
return VortexORM::$orm;
}
public static function set($name, $value) {
$orm = VortexORM::getInstance();
//echo "Setting [ <b>{$name}</b> :: <i>{$value}</i>]";
$orm->$name = $value;
}
public static function get($name) {
$orm = VortexORM::getInstance();
// echo "Getting [ <b>{$name}</b> :: <i>{$orm->$name}</i>]";
return $orm->$name;
}
}
To get data I use:
var_dump(VortexORM::get('admin_links'));
var_dump(VortexORM::get('admin'));
To set data I use:
VortexORM::set('admin_links',array(....));
However, I get the following warnings:
A PHP Error was encountered
Severity: Notice
Message: Undefined property: VortexORM::$admin_links
Filename: Vortex/VortexORM.php
Line Number: 8
NULL
A PHP Error was encountered
Severity: Notice
Message: Undefined property: VortexORM::$admin
Filename: Vortex/VortexORM.php
Line Number: 8
Why am I getting these warnings?
I want to be able to access it like this in CodeIgniter as a static function:
$this->vortexorm->admin_links = array(....);
OK, I just tested this code:
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
class VortexORM {
private static $orm = null;
public function __get($name) {
return $this->$name;
}
public function __set($name, $value) {
$this->$name = $value;
}
public static function getInstance() {
if (VortexORM::$orm == null)
VortexORM::$orm = new VortexORM();
return VortexORM::$orm;
}
public static function set($name, $value) {
$orm = VortexORM::getInstance();
//echo "Setting [ <b>{$name}</b> :: <i>{$value}</i>]";
$orm->$name = $value;
}
public static function get($name) {
$orm = VortexORM::getInstance();
// echo "Getting [ <b>{$name}</b> :: <i>{$orm->$name}</i>]";
return $orm->$name;
}
}
VortexORM::set('admin_links',"test");
var_dump(VortexORM::get('admin_links'));
It just worked fine for me. giving the following output:
string(4) "test"
So, I guess, you were might just trying to retrieve a property before its set? Or please share more details. Also, why are you trying to create new ORM, where we can use doctrine with codeigniter easily?

PHP __set variable while __get passes by reference

I think its quite a simple question but not sure.
I have a class:
<?PHP
class PropertyTest {
private $data = array();
public function __set($name, $value) {
$this->data[$name] = $value;
}
public function __get($name) {
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Undefined property via __get(): ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
public function __isset($name) {
echo "Is '$name' set?\n";
return isset($this->data[$name]);
}
public function __unset($name) {
echo "Unsetting '$name'\n";
unset($this->data[$name]);
}
public function getHidden() {
return $this->hidden;
}
}
?>
Not sure why but the 'code' block is annoying as hell, anyway.
Just the basic magic get set really. But when I change the __get to pass by reference I cant do this anymore:
$object->$variableName = $variableValue;
I'm not sure why although I assume because it checks if it exists but since it has to return something by reference it will fail to do so if it doesn't exists to begin with. The set function wont be called probably and even if I return a fake value it would never call the set function cause it 'already exists/has a value'.
Am I understanding this correctly? If so, Is there a work around? If not how does it work and is there a workaround?
Unless I'm missing something it's working fine for me
<?php
class PropertyTest
{
private $data = array();
public function __set($name, $value)
{
$this->data[$name] = $value;
}
public function &__get($name)
{
if(array_key_exists($name, $this->data))
return $this->data[$name];
return null;
}
public function __isset($name)
{
return isset($this->data[$name]);
}
public function __unset($name)
{
unset($this->data[$name]);
}
public function getHidden()
{
return $this->hidden;
}
}
$oPropTest = new PropertyTest();
$sField = 'my-field';
$oPropTest->$sField = 5;
var_dump($oPropTest);
Outputs:
bash-3.2$ php test-get-set.php
object(PropertyTest)#1 (1) {
["data":"PropertyTest":private]=>
array(1) {
["my-field"]=>
int(5)
}
}
One tweak I'd suggest for your __get implementation is to leverage the __isset method rather than re-implement the check (doing it 2 different ways as you are)
public function __get($name)
{
if($this->__isset($name))
return $this->data[$name];
return null;
}
Regarding the idea of return-by-reference from __get; it will work, but be useless on anything but public attributes, since private and protected attributes won't be settable directly through a reference outside the class scope.
$oPropTest = new PropertyTest();
$sField = 'my-field';
$oPropTest->$sField = 5; // sets $oPropTest->my-field to 5 (effectively)
$iRef = $oPropTest->$sField; // $iRef is a reference to $oPropTest->my-field
$iRef = 6; // this will not set $oPropTest->my-field since it's private

Categories