I'm trying to dig up my long-lost PHP skills and have therefore stumbled on a problem. I have a function that initializes (not sure if it's a correct word for it) a class in the following fashion:
$foo = new \Master\Slave\$bar();
$bar is a defined class, obviously. But the entire thing doesn't work. This only seems to work when I do the following:
$foo = new $bar();
But with my first example, it outputs the following error:
unexpected T_VARIABLE, expecting T_STRING
Which means that I have to manually enter the class name, correct? But, what if I'm a stubborn nerd who doesn't want to and doesn't see the efficiency in it? Hence my question; how to pull this off without getting a bloody error?
UPDATE: Got the thing working with wrapping the \Master\Slave\$bar in a $variable. Not sure if it's the correct way of doing this, but it works and props go to Visual Idiot
Variables never bound to any namespace they will be always in the global scope.
AFAIK, the namespacing does not work the way you are trying to.
This is how you should do it
namespace Master\Slave;
$bar = "theclassname";
class $bar() {
}
Docs
Related
I know you can call static methods using variable as class name like so:
$className = "Foo";
$className::Bar(); //works
But when i'm trying to use static property as variable like this:
self::$className = "Foo";
self::$className::Bar(); //doesn't
it gives me the following parse error on line where i'm trying to call the method:
Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)
So how can i call that method using static property and is that even possible with syntax somewhat similar to what i described(w/o call_user_func and creating local variable that stores self::$className)?
You could do that:
$tmp = self::$className;
$tmp::Bar();
Edit
Based on your comments it seems your problem is more about OOP design than it is about syntax. Furthermore, you keep adding new restrictions every time a solution is given, which makes it difficult to provide a relevant answer.
Anyway, I'll try to summarize your options. The syntax you want does not exist (at the moment, anyway), so you have to work around it one way or another. Yes, this is annoying, and yes this means that you will have to make concessions. But that's how it is.
Here are your options so far:
Use call_user_func or forward_static_call or similar.
Use a temporary local variable. Possibly wrap that into a method if it's really bothering you (e.g. static function call($method) { $tmp = self::$classname; return $tmp::$method(); } and then use self::call('bar');)
Refactor your object design using instances instead of static methods so that you don't need to do that anymore.
Use some other terribly ugly and dangerous hack (e.g. eval(self::$classname.'::bar();'); and hope it won't come bite you in the butt.
Is there a way to make sure that the file exists before using the classes name in a file
This is to avoid errors incase it doesn't exist? I have researched this but nobody tells you how to do it. Maybe thats because there isn't a way or its only a way that secret php coders knew so please dont dislike this question because of the amount of information given about it.
I tried
if (class_exists("Authentication"))
{
use go\Authentication;
}
But I get this error
Parse error: syntax error, unexpected 'use' (T_USE) in C:\xampp\htdocs\index.php on line 29
I also tried this method
if (file_exists("/go/authentication.php") { use go\Authentication; }
And it gave me the same error as the previouse method
Besides of your original intention, in the documentation you can read:
The use keyword must be declared in the outermost scope of a file (the global scope) or inside namespace declarations. This is because the importing is done at compile time and not runtime, so it cannot be block scoped. The following example will show an illegal use of the use keyword:
Which means that it should be used in the top of the file or, at least, in the outermost scope. While your case might be the outermost scope, it is bound to a conditional, which makes your rule illegal, similarly to the example provided in the documentation:
<?php
namespace Languages;
class Greenlandic
{
use Languages\Danish;
...
}
?>
About your problem, you could simply do:
if (class_exists("Authentication"))
$Auth = new Authentication();
However, have a look into autoloading, since that seems more likely what you are looking for.
You are using use wrong!!
The 'use' keyword must be declared in the outermost scope of a file
(the global scope) or inside namespace declarations. This is because
the importing is done at compile time and not runtime, so it cannot be
block
scoped.
As far as loading the class on the fly is concerned. You can use autoloading as suggested in the comments
On a side note. If your class is found inside a namespace such as
namespace foo\bar;
class tar{
}
then the right way to check it exists is not
class_exists('tar')
but rather:
class_exists('\foo\bar\tar')
or
use foo\bar;
class_exists('tar');
Edit:
I solved it by getting all of the class variables using get_class_vars(), and then just acquired the correct property from that array, if it existed. Seems simple enough to me; if anyone has a different solution, I'd love to hear it (or read it, I guess..) :)
I'm trying to access a static variable in a dynamically-loaded class as follows:
$file::$disabled
(In the above statement, $file obviously references the name of a class, and $disabled is the static variable I want to access within the class.)
On PHP 5.3, this works fine; as a result of running the above code on lower versions, I get the infamous T_PAAMAYIM_NEKUDOTAYIM error.
How I've usually gotten around this error when working with older versions of PHP is to create a getter function for that variable and get that return value with call_user_func(). However, for ease of use of developers who will be adopting this code, I would like to keep $disabled as a simple variable rather than a function.
I've tried eval() on the statement, only to reach another dead end.
Does anybody know how I can make this happen?
One option would be to use reflection:
$rp = new ReflectionProperty($file, $disabled);
$value = $rp->getValue();
or
$rc = new ReflectionClass($file);
$value $rc->getStaticPropertyValue($disabled);
Is it possible to get the variable name used to reference an instantiated class from within the class? here's an example of what i mean:
class Test {
function getName(){
//some code here to get the name '$test1' in this example
}
}
$test1 = new Test
It's not a must for this to be possible, but it'd help for a project i'm working on.
You can use the variable $this to reference the object from within itself.
If you want to find the actual name of the variable $test1, it's going to be more difficult (maybe impossible, since the class has no way to know how it is being used in the global scope). But probably not worth it. Most of the time I've seen questions like that asked, people suggest that there's a design flaw and the application should depend on something other than variable names.
You could most likely do it using debug_backtrace(), however this sort of hack is extremely bad practice.
I have followed a tutorial to create a simple blog writing application in PHP and have modified the classes in this tutorial so that they have additional capabilities. Modifying this very bare bones app has given me a better understanding of how PHP works, however I have run across an interesting situation.
One of the classes in my project has about a half dozen class properties such as public $id, public $author, public $post. These properties are declared at the beginning of this class however I find that if I remove all but one of these properties the app still functions correctly.
Is it wrong to remove a property declaration such as public $datePosted from the beginning of a class if this class still assigns variables to this property like this: $this->datePosted = $someVariableName;
If you try to access a class property which hasn't been declared, PHP will issue a notice:
class Foo { }
var $fu = new Foo();
echo $fu->baz;
Notice: Undefined property: Foo::$baz in blah.php on line 4
If you set a value first ($fu->baz = 'blah') then it won't complain, but that's not a great situation.
You should definitely declare all your class variables (unless of course you want to have some fun with the magic methods)...
it's clearer for anyone reading your code that the members have been explicitly defined as public rather than just defaulting to it because you haven't assigned them as being public members.
Also, $this->$datePosted is wrong, it should be like this:
$this->datePosted = $someVariable;
which may be why you are experiencing an error.
PHP is really loose about how it handles class member definitions. You technically don't have to declare them. But you should, for two big reasons:
People with smart IDE's (Eclipse, Aptana, Zend Studio) will love if they can take advantage of their editor's code intellisense (auto-complete) while working with your classes. This feature really helps prevent against bugs involving typos. If you don't declare your fields, the IDE has no real way of determining the class' fields.
Someone just getting done working with a compiled language (C++) will likely send a hitman after you if they see a lack of properly-defined fields. It's just good practice to declare them. There's no reason not to.
Also, if you remove declaration and the code reads this variable prior to writting to it, you will have an error like
PHP Notice: Undefined property:
A::$unexistent in C:\temp\test.php on
line 8
Notice: Undefined property:
A::$unexistent in C:\temp\test.php on
line 8