[FINAL EDIT]
Seems like I've been missing an important Warning contained in Variables variable PHP Manual
http://www.php.net/manual/en/language.variables.variable.php :
Please note that variable variables cannot be used with PHP's Superglobal arrays within functions or class methods. The variable $this is also a special variable that cannot be referenced dynamically.
[ORIGINAL QUESTION]
I've encountered a problem trying to set/get html/server variables $_POST, $_GET, $_SESSION etc.. dynamically using a variable to hold it's name :
// Direct name
${'_GET'}['test'] = '1';
// Variable-holded name
$varname = '_GET';
${$varname}['test'] = '2';
echo "value is " . $_GET['test'];
will output :
value is 1
any idea why?
[EDIT 1]
This is why I want to use it this way :
class Variable {
protected static $source;
public function __get($key) {
// Some validation / var manip needed here
if ( isset( ${self::$source}[$key] ) ) {
return ${self::$source}[$key];
}
}
public function __set($key, $value) {
// Some validation / var manip needed here too
${self::$source}[$key] = $value;
}
}
final class Get extends Variable {
use Singleton;
public static function create() {
parent::$source = "_GET";
}
}
final class Post extends Variable {
use Singleton;
public static function create() {
parent::$source = "_POST";
}
}
final class Session extends Variable {
use Singleton;
public static function create() {
parent::$source = "_SESSION";
}
}
create is called in the singleton constructor when instanciated
[EDIT 2] using PHP 5.4.3
I'm guessing it has something to do with the fact that you shouldn't be assigning values to $_GET like that. Anyhow, this works just fine:
$source = '_GET';
echo ${$source}['test'];
// URL: http://domain.com/thing.php?test=yes
// output: "yes"
edit
Coincidentally, today I went back to update some old code where it looks like I was trying to implement exactly this inside of a class, and it wasn't working. I believe that using the global keyword before attempting to access a superglobal via a variable variable will solve your problem as well.
Class MyExample {
private $method = '_POST';
public function myFunction() {
echo ${$this->method}['index']; //Undefined index warning
global ${$this->method};
echo ${$this->method}['index']; //Expected functionality
}
}
You may be looking for variable variables. Taken from PHP.net:
<?php
$a = 'hello';
?>
<?php
$$a = 'world';
?>
<?php
echo "$a ${$a}";
//returns: hello world
//same as
echo "$a $hello";
?>
EDIT
Another user on php.net had your exact question. Here is his answer.
<?php
function GetInputString($name, $default_value = "", $format = "GPCS")
{
//order of retrieve default GPCS (get, post, cookie, session);
$format_defines = array (
'G'=>'_GET',
'P'=>'_POST',
'C'=>'_COOKIE',
'S'=>'_SESSION',
'R'=>'_REQUEST',
'F'=>'_FILES',
);
preg_match_all("/[G|P|C|S|R|F]/", $format, $matches); //splitting to globals order
foreach ($matches[0] as $k=>$glb)
{
if ( isset ($GLOBALS[$format_defines[$glb]][$name]))
{
return $GLOBALS[$format_defines[$glb]][$name];
}
}
return $default_value;
}
?>
Why not just use $_REQUEST which includes $_GET, $_POST and $_COOKIE? Or am I misunderstanding the purpose?
Related
I would create an array with ID posts from inside a function, and get him outside the class.
My code:
<?php
class cat_widget extends WP_Widget {
private $newHomePost = array();
function widget($args, $instance){
//...
foreach($img_ids as $img_id) {
if (is_numeric($img_id)) {
$this->setNewHomePost($newsCounter,$post->ID);
$newsCounter++;
//...
}
}
}
function setNewHomePost($num, $value){
$newHomePost[$num] = $value;
}
function getNewHomePost(){
return "ID: ".$this->newHomePost[0];
}
}
$testA = new cat_widget();
echo $testA->getNewHomePost();
?>
I receive on screen this resuld:
ID:
(without the id)
But if I insert inside setNewHomePost() an echo for the array, I'll obtain correctly the array but inside and not outside class.
function setNewHomePost($num, $value){
$newHomePost[$num] = $valore;
echo $newHomePost[0];
}
So seem that the array works fine inside the "function widget", but doesn't works outside it.
Can someone help me, please?
function setNewHomePost($num, $value){
$newHomePost[$num] = $value;
}
This creates a local variable named $newHomePost, setting a value at an index and returning. Once it returns, the local variable disappears. From the linked manual page:
Any variable used inside a function is by default limited to the local function scope.
You want to set the class member property newHomePost instead:
function setNewHomePost($num, $value) {
$this->newHomePost[$num] = $value;
}
Update
This is how you currently have the get method defined:
function getNewHomePost() {
return "ID: " . $this->newHomePost[0];
}
I suspect you're still fiddling with this and trying to get it to work. If you really want to just only ever return the 0'th index, try something like this instead:
function getNewHomePost() {
return isset($this->newHomePost[0]) ? $this->newHomePost[0] : null;
}
When building a class remember that you cannot make any assumptions about what order your public methods can be called from another object or calling code (even if the calling code itself exists inside of the class. The methods are public, meaning anything can call them). The code above assumes nothing in that you do not have to call addNewHomePost prior to getNewHomePost. I imagine if you look in your logs you may see a few Notice: Undefined index.. type errors.
Also be sure to check on the calling side:
$myClass = new cat_widget;
$myClass->setNewHomePost(0, 'my new home post!');
$homePost = $myClass->getNewHomePost();
echo $homePost ? $homePost : 'None';
I think a better getter method would probably look like this:
function getNewHomePost($i) {
return isset($this->newHomePost[$i]) ? $this->newHomePost[$i] : null;
}
I'd like to get the class/included variables/elements when I included a php file/class, somehow maybe I should try reflection to do that? If so, how?
For instance, I'd have a PHP class called foo.php:
<?php
class foo
{
public function bar()
{
return "foobar";
}
}
?>
then, in bar.php, I would like to:
<?php
class bar
{
public function foo()
{
$included_resources = include("foo.php"); // Notice, $included_resources is an array
if (($key = array_search("foo", $included_resources)) != false) // "foo" can be any variable or class name
return $included_resources[$key]->bar();
}
}
$helloworld = new bar();
echo $helloworld->foo();
?>
Result: a string value of "foobar" will be represented on the screen
First, store the declared variables in an array before including a file. Then do the include. Then store the declared variables in another array again. Then simply check the difference:
$declared_vars_before = get_defined_vars();
include 'another_file.php';
$declared_vars_after = get_defined_vars();
foreach ($declared_vars_after as $value) {
if (!in_array($value, $defined_vars_before)) {
echo $value . '<br>';
}
}
Same with classes, but use get_declared_classes instead of get_defined_vars.
In PHP, I have the following code (whittled down, to make it easier to read):
class Var {
public $arr;
function __construct($arr) {
$this->arr = $arr;
}
function set($k, $v) {
$this->arr[$k] = $v;
}
}
class Session extends Var {
function __construct() {}
function init() {
session_start();
parent::__construct($_SESSION);
}
}
$s = new Session();
$s->init();
$s->set('foo', 'bar');
var_dump($_SESSION);
At this point, I want $_SESSION to contain 'foo' => 'bar'. However, the $_SESSION variable is completely empty. Why is this the case? How can I store the $_SESSION variable as a property in order to later modify it by reference?
I have tried replacing __construct($arr) with __construct(&$arr), but that did not work.
You needed to take care of reference on every variable re-assignment you have.
So the first place is __construct(&$arr)
The second is $this->arr = &$arr;
Then it should work.
If you didn't put the & in the latter case - it would "make a copy" for the reference you passed in constructor and assign "a copy" to the $this->arr.
PS: It's really weird to call parent constructor from non-constructor method
How to pass a $_GET variable into function?
$_GET['TEST']='some word';
public function example() {
//pass $_GET['TEST'] into here
}
When I try to access $_GET['TEST'] in my function, it is empty.
The $_GET array is one of PHPs superglobals so you can use it as-is within the function:
public function example() {
print $_GET['TEST'];
}
In general, you pass a variable (argument) like so:
public function example($arg1) {
print $arg1;
}
example($myNonGlobalVar);
If this is a function and not an object method then you pass the parameter like so
function example($test) {
echo $test;
}
and then you call that function like so
$_GET['test'] = 'test';
example($_GET['test']);
output being
test
However if this is an object you could do this
class Test {
public function example($test) {
echo $test;
}
}
and you would then call it like so
$_GET['test'] = 'test';
$testObj = new Test;
$testObj->example($_GET['test']);
and the output should be
test
I hope this helps you out.
First of all - you should not set anything to superglobals ($_GET, $_POST, etc).
So we convert it to:
$test = 'some word';
And if you want to pass it to the function just do something like:
function example($value) {
echo $value;
}
And call this function with:
example($test);
function example ($value) {
$value; // available here
}
example($_GET['TEST']);
function example($parameter)
{
do something with $parameter;
}
$variable = 'some word';
example($variable);
Simply declare the value for the variable by
declare the function by
function employee($name,$email) {
// function statements
}
$name = $_GET["name"];
$email = $_GET["email"];
calling the function by
employee($name,$email);
I am using a magic getter/setter class for my session variables, but I don't see any difference between normal setters and getters.
The code:
class session
{
public function __set($name, $value)
{
$_SESSION[$name] = $value;
}
public function __unset($name)
{
unset($_SESSION[$name]);
}
public function __get($name)
{
if(isset($_SESSION[$name]))
{
return $_SESSION[$name];
}
}
}
Now the first thing I noticed is that I have to call $session->_unset('var_name') to remove the variable, nothing 'magical' about that.
Secondly when I try to use $session->some_var this does not work. I can only get the session variable using $_SESSION['some_var'].
I have looked at the PHP manual but the functions look the same as mine.
Am I doing something wrong, or is there not really anything magic about these functions.
First issue, when you call
unset($session->var_name);
It should be the same as calling
$session->_unset('var_name');
Regarding not being able to use __get(); What doesn't work? What does the variable get set to and what warnings are given. Ensure you have set error_reporting() to E_ALL.
It may also be a good idea to check you have called session_start
I thought getters and setters were for variables inside the class?
class SomeClass {
private $someProperty;
function __get($name) {
if($name == 'someProperty') return $this->someProperty;
}
function __set($name, $value) {
if($name == 'someProperty') $this->someProperty = $value;
}
}
$someClass = new SomeClass();
$someClass->someProperty = 'value';
echo $someClass->someProperty;
?
class session { /* ...as posted in the question ... */ }
session_start();
$s = new session;
$s->foo = 123;
$s->bar = 456;
print_r($_SESSION);
unset($s->bar);
print_r($_SESSION);
prints
Array
(
[foo] => 123
[bar] => 456
)
Array
(
[foo] => 123
)
Ok, maybe not "magical". But works as intended.
If that's not what you want please elaborate...
This is my understanding till now about magic function
Please correct me if i am wrong...
$SESSION is an array and not an Object
therefore you can access them using $session['field'] and not $session->field
magic Function allow you to use the function name __fnName before any function as
fnNameNewField($value);
so ,it will be separated into NewField as key and will be sent to __fnName and oprations will be done on this
eg:
setNewId($value) will be sent to __set() with key= new_id and Parameters...