PHP fatal error: " Class '...' not found in ... on line - class

i'm trying to build an API for school project,
i think i have everything right, but for some reason, the code doesn't read the use lines.
use repository\PDOPersonRepository;
use repository\PDOEventRepository;
use view\PersonJsonView;
use view\EventJsonView;
use controller\PersonController;
$user = 'root';
$password = '';
$database = 'wp1';
$pdo = null;
try {
$pdo = new PDO("mysql:host=127.0.0.1;dbname=wp1",
$user, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE,
PDO::ERRMODE_EXCEPTION);
$personPDORepository = new PDOPersonRepository($pdo);
$personJsonView = new PersonJsonView();
$personController = new PersonController($personPDORepository, $personJsonView);
$eventPDORepository = new PDOEventRepository($pdo);
$eventJSonView = new EventJsonView();
$eventController = new EventJsonView($eventJSonView, $eventPDORepository);
Fatal error: Class 'repository\PDOPersonRepository' not found in C:\xampp\htdocs\Werkpakket1\app.php on line 22
phpstorm doesn't give errors in the code, so i don't really understand why it does that

The use lines include classes based on their namespace rather than their physical location. It is different from include or require. If the use keyword is to find the classes, the code of those classes has to be included first.
Another approach is to use a custom autoloader which could match namespaces with the directories of the classes, so that they are loaded automagically only when you need (use) them.
In other words, your code above needs to be prepended with something like:
inculde 'Person.php';
Where that file would contain something like:
namespace repository;
class PDOPersonRepository { ... }
You could use multiple namespaces in a single file, but that is not common practice.

Related

How to add an attribute to an object using the meta-object protocol?

I was trying to answer this question, and thought I could use the meta-object protocol to add attributes to a class. Here is a minimal example where I try to add an attribute test to the class Configuration after construction:
use v6;
class Configuration {
}
my $config = Configuration.new;
my $attr = Attribute.new(
:name('$.test'), # Trying to add a "test" attribute
:type(Str),
:has_accessor(1),
:package(Configuration)
);
$config.^add_attribute( $attr );
$config.^compose();
say "Current attributes: ", join ', ', $config.^attributes();
$attr.set_value( $config, "Hello" ); # <-- This fails with no such attribute '$.test'
say $config.test;
When I run this, I get:
Current attributes: $.test
P6opaque: no such attribute '$.test' on type Configuration in a Configuration when trying to bind a value
in block <unit> at ./p.p6 line 16
Attributes cannot be added after class composition time, which occurs at compile time when the closing } is reached when compiling the program. (This is the case for the P6opaque representation. It's not impossible that a representation could exist that allows this, but there's none specified at this time.)
Further to that, .^add_attribute is called on the meta-object, and for a class the attributes are per type, not per object; the code structure suggests that perhaps the expectation was per object. There's nothing that makes it impossible to have prototype object orientation (actually the MOP is designed so somebody could implement such an object system in Perl 6), but again there's nothing specified in Perl 6 itself that provides this.
Thus with the provided object system, such manipulation needs to be done at compile time, and before the closing }. That can be achieved as follows:
class Configuration {
BEGIN {
my $attr = Attribute.new(
:name('$!test'), # Trying to add a "test" attribute
:type(Str),
:has_accessor(1),
:package(Configuration)
);
Configuration.^add_attribute( $attr );
}
}
my $config = Configuration.new;
say "Current attributes: ", join ', ', $config.^attributes();
$config.^attributes[0].set_value( $config, "Hello" );
say $config.test;
This is one of the many places where Perl 6 is dynamic primarily by inviting the programmer to participate in compile time, rather than by making all things possible at runtime.
Finally, I'll note that there is a means to add attributes to an existing object, and on a per-object basis: by using does to mix a role in to it. That works by changing the type of the object along the way. There's some documentation on does here.

Zend Framework 2 - Instantiating Class

Why do I have to provide the leading backslash when providing the path to a class? [\Zend\Validator\EmailAddress() and not just Zend\Validator\EmailAddress()]
$validator = new \Zend\Validator\EmailAddress();
$email = "example#example.com";
if ($validator->isValid($email)) {
// email appears to be valid
} else {
// email is invalid; print the reasons
foreach ($validator->getMessages() as $messageId => $message) {
echo "Validation failure '$messageId': $message\n";
}
}
Thanks!
You said you've declared the namespace of Blog\Controller at the start of the class, with:
namespace Blog\Controller
This tells PHP that by default all classes referenced within that class are within the Blog\Controller namespace. So if you were to then do:
$validator = new Zend\Validator\EmailAddress();
what you are actually doing is:
$validator = new Blog\Controller\Zend\Validator\EmailAddress();
which would give you an error since that class doesn't exist.
If you prefix a class with the backslash, you're telling PHP that that class is not in your declared namespace, but instead is in the global space, which is why it then works.
You also said you've imported the EmailAddress class using use Zend\Validator\EmailAddress. This allows you to reference that class as simply 'EmailAddress'. So you change your code to:
$validator = new EmailAddress();
which is much more concise. This is one of the advantages of namespaces - it allows you to use shorter class names in your code.

Can I create an instance of a class inside a method of the same class in Perl?

Is it reasonable to create an instance of a class inside a method of the same class?
I ask about "reasonability" and not "feasibility" because I could write a working example, like this:
package MyPkg;
sub new {
...
}
sub myMethod {
my ($class, $param) = #_;
my $obj = $class->new();
...
}
and the usage is:
use MyPkg;
my $result = MyPkg->myMethod("abc");
This architecture does work as expected (in $result I have the result of the call of myMethod on a "transient" object), and the caller is not even forced to explicitly instantiate a new object and then use it to call its methods.
Though, I feel this is not "Perl-ish", I mean... I don't like it. I feel something is flawed with this approach, but can't identify the exact reason.
Is there a more 'standard' solution?
Nothing requires a constructor to have the name new, that's just convention. Your myMethod sub may have a different name, but it's also a constructor.
One example of this is XML::LibXML. It has a standard constructor, but also two other constructors with specific purposes:
use XML::LibXML '1.70';
# Parser constructor
$parser = XML::LibXML->new();
$parser = XML::LibXML->new(option=>value, ...);
$parser = XML::LibXML->new({option=>value, ...});
# Parsing XML
$dom = XML::LibXML->load_xml(
location => $file_or_url
# parser options ...
);
# Parsing HTML
$dom = XML::LibXML->load_html(...);
The second two are probably wrappers for new, but they're also constructors.
Additionally, some objects are designed to be immutable. If they allow operations to still be performed on them, they will need to return a new object of the same type.
All this is to say, yes, what you've doing is fine.
Yes, you can do this. It's quite widely done.

DBIx::Class Wrapping/overloading a column accessor

Using DBIx::Class I am trying to manipulate the data of a column whenever it is being updated or retrieved. For instance, before it goes into the database I would like to encrypt it, and whenever it is being accessed I would like to decrypt it. I am following this example in the DBIx::Class::Manual::Cookbook, however I can't seem to get it to work. I have placed the following in my User schema. For testing I am just using the name column, I know it doesn't make sense:
__PACKAGE__->add_columns("name" => { accessor => '_name' });
sub name {
my $self = shift;
# If there is an update to the column, we'll let the original accessor
# deal with it.
if(#_) {
return $self->_name('test 1');
}
# Fetch the column value.
my $name = $self->_name;
$name = 'test 2';
return $name;
}
I can't see what I'm doing any different than what the cookbook says. Can't anyone help me understand what I'm doing wrong? Thanks!
DBIx::Class has a component for that called FilterColumn.
There are various modules on CPAN using that component like DBIx::Class::EncodedColumn and PassphraseColumn.
If you tell us what you use case is we might give you more/better suggestions.

zend loading models using eval in helpers

i want to load models from helpers... im using eval to insert the modelname etc.
public function getMod($mName) {
// this works but need a dynamic one
$model = $this->users = new Application_Model_Users();
// so i did this:
$model = $this->_listsMod = eval ("new Application_Model_$mName();");
return $model;
and you can call it by: $this->_helper->getmod->getMod('Users')->myuserFunc();
but it doesnt work, its says Fatal error: Call to a member function myuserFunc() on a non-object
Updated answer:
Have you tried:
$modelName = 'Application_Model_'.$mName;
$model = $this->_lists = new $modelName ;
?
You should have a look at the Factory Pattern (which is effectively what you're doing here) eg here and here.
As you probably know, its best to avoid using eval if possible. Also, it seems a bit odd needing to load Models like this - can you tell us why you need to load them like this?
Note: I've updated this answer following comments below, to make it quicker for future readers of the question / answer.