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";
Related
I need to call an function that is part of an object. The following call works as one would expect:
$someobject = getobject();
$result = $someobject->somefunction->value();
However, I need the "somefunction" component to be a variable.
I have tried to do it like this:
$var = 'somefunction';
$result = '$someobject->' . $var '->value'();
This does not work, but I hope it conveys what I am looking for. I've also tried a lot of variations based upon call_user_func() – without finding a syntax that works.
I am running: PHP 7.2.24-0ubuntu0.18.04.3. Vanilla version for Ubuntu 18.04 LTS.
To access a property or method dynamically based on its name, you simply use one more $ sign than you would normally.
For example, if we have this object:
class Foo {
public $someproperty = 'Hello!';
public function somefunction() {
return 'Hello World';
}
}
$someobject = new Foo;
Then we can access the property normally:
echo $someobject->someproperty;
Or dynamically by name:
$var = 'someproperty';
echo $someobject->$var;
Similarly, we can access the method normally:
echo $someobject->somefunction();
Or dynamically by name:
$var = 'somefunction';
$result = $someobject->$var();
Note that your example is a bit confusing, because you talk about "accessing a function where one part is a variable", but all you're actually trying to do is access a property dynamically, and you then happen to be calling a method on the object stored in that property. So the part you've called somefunction is actually the name of a property.
Here's an example that looks a bit like yours, but with the names changed:
class A {
public $foo;
}
class B {
public function value() {
return 'Hello World';
}
}
$a = new A;
$a->foo = new B;
$propertyname = 'foo';
echo $a->$propertyname->value();
class Blueprint
{
public function method()
{
return 'placeholder';
}
}
$object = new Blueprint;
$method = 'method';
// this will output `placeholder`
echo $object->{$method}();
Hooray!
The following (two alternative valid syntaxes are produced for the second line) works as expected without producing any errors:
$foobar = 'somefunction';
$result = $someobject->$foobar->value();
$result = $someobject->{$foobar}->value();
The following:
$foobar = 'somefunction';
$result = $someobject->${foobar}->value();
also works (i.e. it produces the expected result), but it also produces this warning:
Warning: Use of undefined constant foobar - assumed 'foobar' (this will throw an Error in a future version of PHP) …
Many thanks to all that commented. In particular Duc Nguyen and Swetank Poddar. I think it was the comment by Duc Nguyen in combination with the following comment by Swetank Poddar that finally cracked it.
That's the problem, how can I call a class variable from a class function? Let me explain better:
<?php
class Mine
{
private $g = 'gg';
const COSTANTE = 'valo';
public static function sayHello()
{
echo self::COSTANTE;
echo '<br>';
echo $this->g;
}
}
$h = new Mine();
$h->sayHello();
$h::sayHello();
?>
when I run this, it just print the constant COSTANTE.... Why it doesn't print the variable g?
Turn on error reporting ( error_reporting ( E_ALL ); ), and you should receive the following error:
Fatal error: Using $this when not in object context
The pseudo-variable $this is a reference to the calling object, and is available from within an object context.
self is used to access the current class, since static functions can be called without the actual object instance, when the method is called statically $this reference does not exists.
A method declared as static can be accessed with an instantiated class object ( but it is always executed in a static context ), a property declared as static cannot.
valo will be printed but gg and will not.
The issue is because you have used a non-static variable in a static method which will raise a FATAL error and will stop execution. This is because there is no object context.
Its not encouraged to use non-static variable inside static methods but, in case you need to use one, you have to create an object first.
Your sayHello function will be something like
public static function sayHello()
{
echo self::COSTANTE;
echo '<br>';
$mineObject = new Mine;
echo $mineObject->g;
}
I will also suggest keep error reporting and display errors ON while developing so that you can have a better idea of whats happening out there.
error_reporting(E_ALL);
ini_set('display_errors', 'ON');
I'm not so sure what the following object instantiation is called but it comes from a article that i'm reading.
class foo
{
function out()
{
return 'hello';
}
}
echo (new foo())->out();
The object is instantiated automatically and calls the out method. But what i dont really understand is when i rename the out() method into a fictitious method i get an error like this:
example:
class foo
{
function out()
{
return 'hello';
}
}
echo (new foo())->ou();
Fatal error: Call to undefined method foo::ou() in ...
Is this method somehow being called as a static method?
The :: does not stand for static method, this is a missconception. The :: is a "scope resolution operator", it denotes the identification of a method by its class predicated full name.
So this simply means: "method 'ou' as defined by class 'foo'". Not more, not less.
No. The error just indicates that the method doesn't exist. It always shows the :: for this error, no matter whether you call the method in a static way or not. You would get the same error if you changed the code to:
$foo = new foo();
echo $foo->ou();
Second code example as per request in comments:
$moo = new moo(); // Parentheses optional, I guess
$foo = new foo($moo);
$foo->out();
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();
I was trying to debug a PHP script when I came across a declaration like:
$cart = new form;
$$cart = $cart->function();
What is $$cart?
What PHP does when you declare $$cart, is try to get the string value of the $cart object, and use that as the name for this variable variable. This means it'd have to call the __toString() magic method of its class.
If there is no __toString() method in the class, this will cause a catchable fatal error:
Catchable fatal error: Object of class MyClass could not be converted to string...
Otherwise, the name of the $$cart variable variable is the string value of the object as returned by that magic method.
An example with the __toString() magic method implemented (different classes/names but similar to your example calling code):
class MyClass {
public function __toString() {
return 'foo';
}
public function some_method() {
return 'bar';
}
}
$obj = new MyClass();
$$obj = $obj->some_method();
echo (string) $obj, "\n"; // foo
echo $$obj; // bar
the double $ is used for a variable variable.
essentially what this entails is the second $ along with the word is a variable the value of which is used for the name of the first $
i.e.-
$first = "second";
$second = 'Goodbye';
echo $$first; // Goodbye