Is there such a thing as local, private, static and public variables in PHP? If so, can you give samples of each and how their scope is demonstrated inside and outside the class and inside functions?
I don't know about C++ but there's how PHP works about:
For Function scopes:
<?php
$b = 6;
function testFunc($a){
echo $a.'-'.$b;
}
function testFunc2($a){
global $b;
echo $a.'-'.$b;
}
testFunc(3);
testFunc2(3);
?>
The output is
3-
3-6
Code inside functions can only be accessed variables outside functions using the global keyword. See http://php.net/manual/en/language.variables.scope.php
As for classes:
<?php
class ExampleClass{
private $private_var = 40;
public $public_var = 20;
public static $static_var = 50;
private function classFuncOne(){
echo $this->private_var.'-'.$this->public_var; // outputs class variables
}
public function classFuncTwo(){
$this->classFuncOne();
echo $private_var.'-'.$public_var; // outputs local variable, not class variable
}
}
$myobj = new ExampleClass();
$myobj->classFuncTwo();
echo ExampleClass::$static_var;
$myobj->classFuncOne(); // fatal error occurs because method is private
?>
Output would be:
40-20
-
50
Fatal error: Call to private method ExampleClass::classFuncOne() from context '' in C:\xampp\htdocs\scope.php on line 22
One note to take: PHP does not have variable initialization, although variables are said to be set or not set. When a variable is set, it has been assigned with a value. You can use the unset to remove the variable and its value. A not set variable is equivalent to false, and if you use it with all errors output, you will see a E_NOTICE error.
In PHP there are static, local, private, public, and protected class variables.
However, in the PHP OOP implementation things are a little different: the manual will help you:
The visibility of a property or method
can be defined by prefixing the
declaration with the keywords public,
protected or private.
Furthermore, have a look at the static keyword documentation.
You'll be able to read more about normal variables and their scope here: http://php.net/manual/en/language.variables.scope.php:
For the most part all PHP variables only have a single scope.
I hope the links will be able to explain it to you better than I did ;-)
yes, PHP 5 incldude static variables and visibility in class.
class MyClass
{
public static $my_static = 'foo';
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
public function staticValue() {
return self::$my_static;
}
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello(); // Shows Public, Protected and Private
Related
It's possible to extend classes during runtime, and I've been playing around with it a bit, but then I stumbled upon this, which to me is strange. If I define a new variable in a private function it becomes a public variable. Shouldn't it at least be protected?
Here's the code that I've used to test this:
class FooBar {
public function FooBar() {
$this->t();
}
public function createVariable() {
$this->NewVar();
}
private function NewVar() {
$this->iam = "Hello you!";
}
private function t() {
$this->T = "ballad";
return $this->T;
}
}
$fb = new FooBar();
echo $fb->T;
echo "<br/>";
var_dump($fb);
$fb->createVariable();
echo $fb->iam;
echo "<br/>";
var_dump($fb);
echo "<br/>";
$fb->outer = "okay";
echo $fb->outer;
And as an extra, since it's possible to extend a class during runtime why isn't this possible:
function foo() {
private $this->anewvar = 0; //private is illegal.
}
PHP allows variables to be instantiated at any time without explicitly defining them.
But since you haven't defined the variable explicitly, PHP doesn't know how you want it to be scoped, and it has no way for you to tell it either, so it just goes with the safest possible option and makes it public.
If you want it scoped privately, define it as a private variable in the class definition.
I'm new to PHP and practicing using static variables. I decided to grab an example that I learnt from C++ and re-write it for PHP (example from the bottom of this article).
There's a class with two private variables (one static), a constructor and a get-method. The constructor assigns the static variable's value to the second private variable, and then increments.
<?php
class Something
{
private static $s_nIDGenerator = 1;
private $m_nID;
public function Something() {
$m_nID = self::$s_nIDGenerator++;
echo "m_nID: " . $m_nID . "</br>"; //for testing, can comment this out
}
public function GetID() {
return $m_nID;
}
}
// extra question:
// static variable can be assigned a value outside the class in C++, why not in PHP?
// Something::$s_nIDGenerator = 1;
$cFirst = new Something();
$cSecond = new Something();
$cThird = new Something();
echo $cFirst->GetID() . "</br>";
echo $cSecond->GetID() . "</br>";
echo $cThird->GetID() . "</br>";
?>
Using the echo test in line 9 to see if m_nID is getting a value I see:
m_nID: 1
m_nID: 2
m_nID: 3
But these values are not being returned by the "->GetID()" calls. Any ideas why?
Edit: both replies so far have solved this, I wish I could "check" them both, so thank you! I'll leave the original code in the question as-is for any future people who have a similar problem
Your background in C++ led up to this issue, which is an easy mistake to make. In PHP, all instance (or object) variables are referenced using $this->, and static (or class) variables with self::. Based on your code:
public function GetID() {
return $m_nID;
}
Access to the private variable $m_nID should be scoped like this:
public function GetID() {
return $this->m_nID;
}
And inside your constructor:
$m_nID = self::$s_nIDGenerator++;
It should have been:
$this->m_nID = self::$s_nIDGenerator++;
Q & A
Why is there no need to put $ before m_nID when using $this->
The above two ways of referencing instance and class variables come with a very different kind of syntax:
$this is the instance reference variable and any properties are accessed using the -> operator; the $ is not repeated for the property names themselves, although they're present in the declaration (e.g. private $myprop).
self:: is synonymous to Something:: (the class name itself); it doesn't reference an instance variable and therefore has no $ in front of it. To differentiate static variables from class constants (self::MYCONST) and class methods (self::myMethod()) it's prefixed with a $.
Extra
That said, $this->$myvar is accepted too and works like this:
private $foo = 'hello world';
function test()
{
$myvar = 'foo';
echo $this->$foo; // echoes 'hello world'
}
class Something{
private static $s_nIDGenerator = 1;
private $m_nID;
public function Something() {
$this->m_nID = self::$s_nIDGenerator++;
}
public function GetID() {
return $this->m_nID;
}
}
It is interesting to note the difference between using self::$s_nIDGenerator on a static variable vs using $this->s_nIDGenerator on a static variable, whereas $this-> will not store anything.
I have found different information regarding static variables in PHP but nothing that actually explains what it is and how it really works.
I have read that when used within a class that a static property cannot be used by any object instantiated by that class and that a static method can be used by an object instantiated by the class?
However, I have been trying to research what a static variable does within a function that is not in a class. Also, does a static variable within a function work somewhat like closure in javascript or am I totally off in this assumption?
I have read that when used within a class that a static property cannot be used by any object instantiated by that class
It depends on what you mean by that. eg:
class Foo {
static $my_var = 'Foo';
}
$x = new Foo();
echo $x::$my_var; // works fine
echo $x->my_var; // doesn't work - Notice: Undefined property: Foo::$my_var
and that a static method can be used by an object instantiated by the class???
Yes, an instantiated object belonging to the class can access a static method.
The keyword static in the context of classes behave somewhat like static class variables in other languages. A member (method or variable) declared static is associated with the class and rather than an instance of that class. Thus, you can access it without an instance of the class (eg: in the example above, I could use Foo::$my_var)
However, I have been trying to research what a static variable does within a function that is not in a class.
Also, does a static variable within a function work somewhat like closure in javascript or am I totally off in this assumption.
Outside of classes (ie: in functions), a static variable is a variable that doesn't lose its value when the function exits. So in sense, yes, they work like closures in JavaScript.
But unlike JS closures, there's only one value for the variable that's maintained across different invocations of the same function. From the PHP manual's example:
function test()
{
static $a = 0;
echo $a;
$a++;
}
test(); // prints 0
test(); // prints 1
test(); // prints 2
Reference: static keyword (in classes), (in functions)
static has two uses in PHP:
First, and most commonly, it can be used to define 'class' variables/functions (as opposed to instance variables/functions), that can be accessed without instantiating a class:
class A {
public static $var = 'val'; // $var is static (in class context)
public $other_var = 'other_val'; // non-static
}
echo A::$var; // val
echo A::$other_var // doesn't work (fatal error, undefined static variable)
$a = new A;
echo $a->var // won't work (strict standards)
echo $a->other_var // other_val
Secondly, it can be used to maintain state between function calls:
function a() {
static $i = 0;
$j = 0;
return array($i++, $j++);
}
print_r(a()); // array(0, 0)
print_r(a()); // array(1, 0)
print_r(a()); // array(2, 0)
//...
Note that declaring a variable static within a function works the same regardless of whether or not the function is defined in a class, all that matters is where the variable is declared (class member or in a function).
A static variable in a function is initialized only in the first call of that function in its running script.
At first i will explain what will happen if static variable is not used
<?php
function somename() {
$var = 1;
echo $var . "<br />";
$var++;
}
somename();
somename();
somename();
?>
If you run the above code the output you gets will be 1 1 1 . Since everytime you called that function variable assigns to 1 and then prints it.
Now lets see what if static variable is used
<?php
function somename() {
static $var = 1;
echo $var . "<br />";
$var++;
}
somename();
somename();
somename();
?>
Now if you run this code snippet the output will be 1 2 3.
Note: Static keeps its value and stick around everytime the function is called. It will not lose its value when the function is called.
class Student {
static $total_student = 0;
static function add_student(){
return Student::$total_student++;
}
}
First: for the add_student function, the best practice is to use static not public.
Second: in the add_student function, we are using Student::$total_student,not use $this->total_student. This is big different from normal variable.
Third:static variable are shared throughout the inheritance tree.
take below code to see what is the result:
class One {
static $foo ;
}
class Two extends One{}
class Three extends One{}
One::$foo = 1;
Two::$foo = 2;
Three::$foo = 3;
echo One::$foo;
echo Two::$foo;
echo Three::$foo;`
I trying to learn OOP and I've made this class
class boo{
function boo(&another_class, $some_normal_variable){
$some_normal_variable = $another_class->do_something();
}
function do_stuff(){
// how can I access '$another_class' and '$some_normal_variable' here?
return $another_class->get($some_normal_variable);
}
}
and I call this somewhere inside the another_class class like
$bla = new boo($bla, $foo);
echo $bla->do_stuff();
But I don't know how to access $bla, $foo inside the do_stuff function
<?php
class Boo
{
private $bar;
public function setBar( $value )
{
$this->bar = $value;
}
public function getValue()
{
return $this->bar;
}
}
$x = new Boo();
$x->setBar( 15 );
print 'Value of bar: ' . $x->getValue() . PHP_EOL;
Please don't pass by reference in PHP 5, there is no need for it and I've read it's actually slower.
I declared the variable in the class, though you don't have to do that.
Ok, first off, use the newer style constructor __construct instead of a method with the class name.
class boo{
public function __construct($another_class, $some_normal_variable){
Second, to answer your specific question, you need to use member variables/properties:
class boo {
protected $another_class = null;
protected $some_normal_variable = null;
public function __construct($another_class, $some_normal_variable){
$this->another_class = $another_class;
$this->some_normal_variable = $some_normal_variable;
}
function do_stuff(){
return $this->another_class->get($this->some_normal_variable);
}
}
Now, note that for member variables, inside of the class we reference them by prefixing them with $this->. That's because the property is bound to this instance of the class. That's what you're looking for...
In PHP, constructors and destructors are written with special names (__construct() and __destruct(), respectively). Access instance variables using $this->. Here's a rewrite of your class to use this:
class boo{
function __construct(&another_class, $some_normal_variable){
$this->another_class = $another_class;
$this->some_normal_variable = $another_class->do_something();
}
function do_stuff(){
// how can I access '$another_class' and '$some_normal_variable' here?
return $this->another_class->get($this->some_normal_variable);
}
}
You need to capture the values in the class using $this:
$this->foo = $some_normal_variable
Below code works fine:
<?php session_start();
$_SESSION['color'] = 'blue';
class utilities
{
public static $color;
function display()
{
echo utilities::$color = $_SESSION['color'];
}
}
utilities::display(); ?>
This is what I want but doesn't work:
<?php session_start();
$_SESSION['color'] = 'blue';
class utilities {
public static $color = $_SESSION['color']; //see here
function display()
{
echo utilities::$color;
} } utilities::display(); ?>
I get this error: Parse error: syntax error, unexpected T_VARIABLE in C:\Inetpub\vhosts\morsemfgco.com\httpdocs\secure2\scrap\class.php on line 7
Php doesn't like session variables being stored outside of functions. Why? Is it a syntax problem or what? I don't want to have to instantiate objects because for just calling utility functions and I need a few session variables to be stored globally. I do not want to call a init() function to store the global session variables every time I run a function either. Solutions?
In a class you can use SESSION only in methods...
Actually, if you want to do something in a class, you must code it in a method...
A class is not a function. It has some variables -as attributes- and some functions -as method- You can define variables, you can initialize them. But you can't do any operation on them outside of a method...
for example
public static $var1; // OK!
public static $var2=5; //OK!
public static $var3=5+5; //ERROR
If you want to set them like this you must use constructor... (but remember: constructors aren't called until the object is created...)
<?php
session_start();
$_SESSION['color'] = 'blue';
class utilities {
public static $color;
function __construct()
{
$this->color=$_SESSION['color'];
}
function display()
{
echo utilities::$color;
}
}
utilities::display(); //empty output, because constructor wasn't invoked...
$obj=new utilities();
echo "<br>".$obj->color;
?>
From the PHP manual:-
Like any other PHP static variable,
static properties may only be
initialized using a literal or
constant; expressions are not allowed.
So while you may initialize a static
property to an integer or array (for
instance), you may not initialize it
to another variable, to a function
return value, or to an object.
You say that you need your session variables to be stored globally? They are $_SESSION is what is known as a "super global"
<?php
class utilities {
public static $color = $_SESSION['color']; //see here
function display()
{
echo $_SESSION['color'];
}
}
utilities::display(); ?>