Class 'XMLParser' not found - php

I've created a class called XMLParser which is being inlcuded using an auto include like all the other classes I'm working with.
When I try to instantiate an object using this class, I get the fatal error in the title.
The auto-include function works. Changing the class name makes it work, I'm also quite positive this had been working when I set it up, otherwise the unit tests depending on this class would never have passed.
Is there a built in XMLParser class that could be conflicting with this?
Surely, even if there was that would not be a problem as I'd get a declaration error or the object would just be instantiated anyway?
Any light on the matter would really help. It's frustrating to say the least.

There is a PEAR file called XMLParser.php
This file appears in the PHP include path before my class directories.
When the autoload function requires_once XMLParser.php it finds this file, which rightfully, does not have the XMLParser class defined within.
That's the source of the fatal error.
To avoid this, one should probably namespace their classes.
Shame on me, thanks for all your feedback.

Related

How do I access a subclass's functions using namespaces?

So, I have a few classes I'm trying to use PHP's namespaces with and am having some trouble accessing the functions in the lowest level class.
Here's how it's laid out...
Activity -> Post
Activity has a namespace of activity and Post has a namespace of post
At the top of my Post class I have this code.
namespace Post;
use activity\activity;
That's the code that PHPStorm created when I made my class file and then extended my Activity class.
So, when I try to access my public functions inside Post, I have tried both of these methods...
\activity\post::function();
AND
$post = new \activity\post();
$post->function();
But PHPStorm tells me neither of those exist.
So, what's the actual way to access these lower level functions?
I've googled quite a bit but apparently I'm not searching for the right thing because I haven't found anything about sub classes.
Thanks so much for your help in understanding how this works.
Don't use \activity, use activity.
\activity is using the \ (or base) namespace.
Use doesn't extend a class, it creates an alias. Since you have Use activity\activity this makes it so you can access functions in the activity class by running activity::function() rather than using the full namespace \activity\activity::function().
You can also define use \activity\activity as test and access functions like test::function().
I'm not sure of the point of having the namespaces the same name as the classes though but sjagr addressed that in comments.

Instantiate a PHP stdClass in my namespace – fatal error

I want to write a small add on for an existing CMS. To do so, I need to extend a class from that CMS' code.
My code will be written inside its own namespace, while the CMS' code does not use namespacing, which basically means it exists inside the global namespace.
Inside my code, I create a new stdClass:
$var = new stdClass();
With that code is place, it always produces a fatal error:
Fatal error: Class 'MyNamespace\something\StdClass' not found in /some/rather/long/path/to/class.php on line 123
Creating the stdClass like this solves that problem:
$var = new \stdClass();
Since I am still pretty new to namespaces, I am not exactly sure what the problem here is?
My guess is that in the first example, the stdClass would be created in the namespace of my class. This actually means the constructor of a class called stdClass existing in my namespace would be called, but since that class does not exist, an error is thrown.
In the second example, I signalize that I want to instantiate the class called stdClass from the global namespace, which somehow suddenly makes sense.
If anyone could elaborate what is happening here I would be very happy.
You appear to understand the concept behind namespaces, and you are headed in the right direction on your analysis of what is happening.
When you are working inside of a namespace you are able to refer to names as unqualified, qualified, and fully qualified.
When you make a namespace you are telling PHP to organize (and resolve) the names of your classes, function, methods, etc. away from the same scope where the built-in PHP code lives along with any other code behind its own namespace. It is away to organize your code and avoid naming collisions among libraries and built-in PHP functions.
Here is a brief on how names get resolved:
If you are trying to resolve a name within the same namespace you can use the unqualified name. So for class \Foo\Bar\Baz you can use new Baz(); as long as you are in namespace \Foo\Bar.
If you are trying to resolve a name that is lower in the same parent namespace you can use the qualified name. So for class \Foo\Bar\Baz you would need to use new Bar\Baz(); if you were in namespace \Foo.
If you are trying to resolve a name that is not in your namespace or is in the global namespace (built-in PHP stuff) then you must use the fully qualified name. If you are in namespace \Foo\Bar and you want to make use of something like the mysqli class you would need to call it by its fully qualified name. e.g. new \mysqli() Your question above is a perfect example that illustrates this. Likewise, if you need to access a class in a totally different namespace you would also need the fully qualified name: new \Third\Party\AppClass();
So to summarize, you are right, the built-in stdClass does not exist in your namespace, therefore you need to access it by the fully qualified name. The reason you must do thing this way had to do with conforming to the rules PHP uses when resolving names.
If you ever need to find out what namespace you are in it will be in the __NAMESPACE__ constant.
In case you haven't already read it, here is the documentation on name resolution in PHP: http://php.net/manual/en/language.namespaces.rules.php
The code is evaluated in your namespace and stdClass doesn't exist there. You are effectively answering your own question with your guess.
Your guess is correct. Look at the comments in "class references" section of Example #1 on this page.
http://php.net/manual/en/language.namespaces.rules.php

How to definitively determine if an object was instantiated

I have a PHP class which I'm instantiating an object for. If I change the namespace of the class of change the path of the class, the autoloader complains that that class is not defined. But when I do everything correctly, there are no complaints but the echo in the constructor is not triggered. So I'm assuming it found the class, but then why is the constructor code not triggered? How can I definitely tell that an object has been instantiated?
$obj = new MyClass()?
How to check whether $obj is instantiated properly?
For the original question, please see here. spl_autoload_register issue while loading class
Any answers you can provide there is also highly appreciated. I'm trying to break a bigger problem into several smaller ones to solve it.

Newbie php class inheritance question

I had a problem recently with a php project that I finally realised was down to the way I had structured my classes. If I tried to include more than one class in a page and both classes shared the same parent class, the script failed. I've now resolved the issue but was wondering if someone could explain to me exactly why what I was doing wasn't working, cos I haven't quite got my head around it!
Here's an illustration of what did NOT work:
class A.
class B extends A.
class C extends A.
class D extends B.
class E extends C.
I require class D and class E and the script fails. If class C does not inherit A then it all works fine.
Obviously, it's something to do with requiring class A twice, but could someone explain it in very simple terms for me?!?!?
You may declare every class only once. If you require the file where your class is defined more than once, the parser encounters the class A, makes an internal lookup and bails: 'Hey, you've already defined that class'. The most simple solution is to put every class into its own file and call require_once instead of require.
Do you have each class in its own file?
Are you using require/include instead of require_once/include_once ?
include_once and require_once do not share the same table of included files either, so you have to use one consistently.
Or consistently use the __autoload function in PHP5.
Any functions or classes defined in included files are declared in the global scope. This is why you are probably getting redeclaration errors. The solution is to use require_once or include_once instead of require or include.
The most elegant way though, is to use a __autoload, but that requires PHP version 5 or later. The only downside to autoloading is that any failure is a fatal error which you can't handle yourself.

Find where a class was instantiated

I have trying to solve the error : Fatal error: Cannot redeclare class
I have been looking everywhere and I can't find where the class was instantiated.
Is there anyway I can print debug info about the existing instance of that class.
Chances are you are importing the file that declares the class more than once. This can be symptomatic of includes/requires getting out of control so you may need to simply your structure.
One alternative approach is to use autoload to load classes to avoid this kind of problem. Another is to only use include_once or require_once. I generally prefer to use require with a simple structure.
Yes, stupid php doesn't tell you where the class was declared. Try the following (immediately before fatal error line)
$r = new ReflectionClass("YourClassName"); echo $r->getStartLine();
You can find out, where an object was instantiated by using var_dump(debug_backtrace()); and looking at the call stack.

Categories