I'm using constants for my error messages inside the Views, and I want to be able to use variables inside them for easier management.
Most of my constants looks like this:
const SUCCESSFULLY_REGISTERED = "<p class='success'>Registration successful!.</p>";
What I want to do is to use a variable for the css class, so that it's easier to change them all in one place. This is what I've tried:
const SUCCESSFULLY_REGISTERED = "<p class='$this->cssClassSuccess'>Registration successful!.</p><p>Log in with the username and password you registered with.</p>";
By some reason that doesn't work and raises the error message below. Why is that and how can this be done in a way that works?
Parse error: syntax error, unexpected '"' in .../View/RegisterView.php on line 15
This is not possible if you define a constant.
Manual: "The value must be a constant expression, not (for example) a variable, a property, a result of a mathematical operation,
or a function call."
Constant Manual php.net
Constant Expression
This won't work because constants (as the name implies) need to be constant, but you can work around it with printf().
Example:
const SUCCESSFULLY_REGISTERED = '<p class="%s">Registration successful blah blah blah!</p>'
And then in your view script:
printf(SUCCESSFULLY_REGISTERED, $this->cssClassSuccess);
The %s in the constant will be replaced with the value of $this->cssClassSuccess
Manual: As of PHP 5.3.0, it's possible to reference the class using a variable.
Check the following class below:
<?php
class A{
function __construct($v)
{
define("MyConstant",$v);
echo "MyConstant is ". MyConstant;
}
}
$a = new A("hello"); //will print MyConstant is hello
?>
In the code above we are assigning the value of a variable ($v) to constant MyConstant. It will not give an error and the result of running this function will be MyConstant is hello
However, suppose you added a new line like so:
$a = new A("hello"); //will print MyConstant is hello
$b = new A("New Value"); //will generate Constant MyConstant already defined notice..
Here the line $b = new A("New Value"); will throw a notice stating: Notice: Constant MyConstant already defined. This is because constants defined within a class are pseudo-class-constants, similar to being static variables in terms of the context to which the scope is bound. And since constants cannot be changed, and their scope is bound to the class, calling the error line above is essentially trying to "redefine" the constant, which as you know will result in the aforementioned error.
Having said that remember that if you use define to create a constant inside a class it is not a pure class constant - you cannot call it as A::MyConstant. At the same time if you had done const AnotherConstant = "Hey"; in Class A you can call it as A::AnotherConstant. However when using const to create a constant you cannot set its value to a variable.
I hope this gives a better clarity on how dynamic variables can and cannot be assigned to a constant.
The only way that you can dynamically generate a constant is using the define function like below. But as another answer pointed out, this won't be a class level constant.
define('SUCCESSFULLY_REGISTERED', "<p class='$this->cssClassSuccess'>Registration successful!.</p><p>Log in with the username and password you registered with.</p>");
The constant from that point forward can be referred to with SUCCESSFULL_REGISTERED and will be immutable.
Problem: Cast custom messages and pass variables for easier management
Solution: use a Decorator pattern
interface HtmlElementInterface {
public function getText();
public function render();
}
class DivDecorator implements HtmlElementInterface {
protected $innerHtml;
protected $class;
public function __construct($class = null, $innerHtml = null) {
$this->innerHtml = $innerHtml;
$this->class = $class;
}
public function getText() {
return $this->text;
}
public function render() {
return "<div class='{$this->class}'>" . $this->innerHtml . "</div>";
}
}
$message = "Error in the app";
$div = new DivDecorator("myclass", $message);
echo $div->render();
Related
I have a page with the following class:
class SimpleClass
{
public $var6 = myConstant;
public $var7 = array(true, false);
}
And I ran the page on browser. It throws no errors/warning/notice.
But then I created an object like:
$newvar = new SimpleClass;
echo $newvar->var6;
And it gives me "Notice: Use of undefined constant myConstant".
I know myConstant needs to be defined to be accessed, which has not been.
My question is why am I getting this Notice message only after object creation and not before?
You're getting the error because you're instantiating the class in the second example.
$newvar = new SimpleClass();
This throws the error as it tries to "compile" it, thus trying to harness myConstant within the global namespace, hence the error (as it isn't defined).
If you don't call the class, you wouldn't have the error throwing as it isn't in use.
Clarification on your comment here:
You only get the error message due to the fact that you instantiated the class. If you didn't do that, the error wouldn't show. This is correct practice and exactly how PHP functions.
here when you are trying to retrieve the $var6, It is assuming it like public $var6 = 56; //any constant .
read about how to declare constant , if you want constant there. Or use quote , so that it will treat it as string.
string
<?php
class SimpleClass
{
public $var6 = 'myConstant';
public $var7 = array(true, false);
}
$newvar = new SimpleClass;
echo $newvar->var6;
constant
class MyClass
{
const CONSTANT = 'constant value';
}
echo MyClass::CONSTANT . "\n";
I need to assign a class (not an object) to a variable. I know this is quite simple in other programming languages, like Java, but I can't find the way to accomplish this in PHP.
This is a snippet of what I'm trying to do:
class Y{
const MESSAGE = "HELLO";
}
class X{
public $foo = Y; // <-- I need a reference to Class Y
}
$xInstance = new X();
echo ($xInstance->foo)::MESSAGE; // Of course, this should print HELLO
In php you cannot store a reference to a class in a variable. So you store a string with class name and use constant() function
class Y{
const MESSAGE = "HELLO";
}
class X{
public $foo = 'Y';
}
$xInstance = new X();
echo constant($xInstance->foo . '::MESSAGE');
You could use reflection to find it (see Can I get CONST's defined on a PHP class?) or you could a method like:
<?php
class Y
{
const MESSAGE = "HELLO";
}
class X
{
function returnMessage()
{
return constant("Y::MESSAGE");
}
}
$x = new X();
echo $x->returnMessage() . PHP_EOL;
edit - worth also pointing out that you could use overloading to emulate this behaviour and have access to a property or static property handled by a user defined method
I found out that you can treat a reference to a Class just like you would handle any regular String. The following seems to be the simplest way.
Note: In the following snippet I've made some modifications to the one shown in the question, just to make it easier to read.
class Y{
const MESSAGE="HELLO";
public static function getMessage(){
return "WORLD";
}
}
$var = "Y";
echo $var::MESSAGE;
echo $var::getMessage();
This provides a unified mechanism to access both constants and/or static fields or methods as well.
I have a class look like below:
<?php
class theGodFather {
public function do() {
echo "the movie is nice";
}
}
$obj = new theGodFather;
echo $theGodFather->do;
When run I got the error: syntax error, unexpected T_DO, expecting T_STRING in /Applications/XAMPP/xamppfiles/htdocs/test/classes.php on line 3
what could I possibly did wrong?
You cannot use keywords as names for functions/classes/methods and constants, do is one. You can use them as variable names, however.
"do" is a keyword (can be used in a do while loop). Also you're echoing a function that returns nothing, but echoes something in it.
Rename the "do" function to "echoFunction" or whatever name you choose and then
change this:
$obj = new theGodFather;
echo $theGodFather->do;
to:
$obj = new theGodFather;
$obj->echoFunction();
The reason you wouldn't call $theGodFather->echoFunction because theGodFather is a class definition, while $obj is an actual instance of the class. You can have static methods in PHP that you can call without creating a new instance.
you have use do function in class "do" is a keyword of php and you cannot use keyword in function or class
try this
class theGodFather
{
// property declaration
public $var = 'a default value';
// method declaration
public function displayVar() {
echo 'a default value';
}
}
$obj = new theGodFather();
//print_r($obj);
echo $obj->displayVar();
do is a keyword, therefore the interpreter gets very very confused. :(
Choose a different function name and it works!
Example:
class LOL{
const
FOO = 1;
}
$x = new LOL;
$arr = array('x' => $x);
echo $x::FOO; // works
echo $arr['x']::FOO; // works too
But if I make my class instance a property, I can't access the constant anymore:
class WWW{
protected $lol;
public function __construct($lol){
$this->lol= $lol;
}
public function doSMth(){
echo $this->lol::FOO; // fail. parse error.. wtf
}
}
$w = new WWW;
$w->doSMth();
:(
I know I can just do echo LOL::FOO, but what if the class name is unknown? From that position I only have access to that object/property, and I really don't want that WWW class to be "aware" of other classes and their names. It should just work with the given object
You can do this much easier by assigning the lol property to a local variable, like so:
public function doSMth(){
$lol = $this->lol;
echo $lol::FOO;
}
This is still silly, but prevents having to use reflections.
If the class name is not known, you can use ReflectionClass to get the constant. Note you must be using PHP 5 or greater.
Example:
$c = new ReflectionClass($this->lol);
echo $c->getConstant('FOO'); // 1
As of PHP 5.3.0, you can access the constant via a variable containing the class name:
$name = get_class($this->lol);
echo $name::FOO; // 1
For more info, see Scope Resolution Operator - PHP
$lol = &$this->lol;
echo $lol::FOO;
..
unset($lol);
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;`