Zend Framework 2 - Instantiating Class - 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.

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.

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

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.

Fuelphp input and session issue in model

I ran into a problem what i cant really solve (i am a begginer with fuelphp).
So when i place input in my model i get this error
ErrorException [ Error ]: Class 'Model\Input' not found
when i try with session its the same thing
ErrorException [ Error ]: Class 'Model\Session' not found
And when i try to hardcode a value in it its not inserting, debuged the query no errors. it shows the value is posted (when passing hard code value) but not inserts it in the database.
my code
model
namespace Model;
use DB;
class Event extends \Model {
static function send_event()
{
$query = DB::insert('events');
$query->set(array(
'user_id' => Session::get('sentry_user'),
'event_name' => Input::post('event_name'),
'event_desc' => Input::post('event_desc'),
'event_start' => Input::post('event_start'),
'event_end' => Input::post('event_end'),
));
}
}
controller
function action_send_data()
{
$response = Response::forge();
$val = Validation::forge('events');
$val->add_field('event_name', 'Esemény neve', 'required');
$val->add_field('event_desc', 'Esemény leírás', 'required');
$val->add_field('event_start', 'Esemény kezdődik', 'required');
$val->add_field('event_end', 'Esemény kejár', 'required');
Event::send_event();
$response->body(json_encode(array(
'status' => 'ok',
)));
return $response;
}
could please someone give me a hint what i am doing wrong?
thank you
P.S: in the controller i removed the validation for query debuging
When you declare a namespace at the top of a file as you have done with
namespace Model;
This declares the namespace for all classes called where the namespace is not explicitly defined. For example, your call to Session is actually looking in Model\Session when it actually exists in \Fuel\Core\Session
There are two ways around this. You've demonstrated an example yourself in your question with a call to the use language construct.
use DB;
This causes PHP to search for classes in this namespace as well as the one which is already being used (Model in this case).
The other way you can do it is by calling the class with the explicit namespace. For example
\Fuel\Core\Session::get();
Fuel also aliases all core classes to the root namespace for convenience. What this means is you can also directly call classes in \Fuel\Core just using \. For example
\Session::get();

How to use Zend Framework's Partial Loop with Objects

I am quite confused how to use partialLoop
Currently I use
foreach ($childrenTodos as $childTodo) {
echo $this->partial('todos/_row.phtml', array('todo' => $childTodo));
}
$childrenTodos is a Doctrine\ORM\PersistantCollection, $childTodo is a Application\Models\Todo
I tried doing
echo $this->partialLoop('todos/_row.phtml', $childrenTodos)
->setObjectKey('Application\Models\Todo');
But in the partial when I try to access properties/functions of my Todo class, I cant seem to get them always ending up with either call to undefined method Zend_View::myFunction() when I use $this->myFunction() in the partial or if I try $this->todo->getName() I get "Call to a member function getName() on a non-object". How do I use partialLoops?
Try this
echo $this->partialLoop('todos/_row.phtml', $childrenTodos)
->setObjectKey('object');
Then in your partial you can access the object like this
$this->object
object is the name of the variable that an object will be assigned to
You can also do this once in your Bootstrap or other initialization class if you have access to the view object like so
protected function initPartialLoopObject()
{
$this->_view->partialLoop()->setObjectKey('object');
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->setView($this->_view);
}
I also had "Call to function on non object" error when trying suggested syntax, seems like they've changed something on later versions of Zend Framework. The following works for me on ZF1.12:
echo $this->partialLoop()
->setObjectKey('object')
->partialLoop('todos/_row.phtml', $childrenTodos);

How to change the separation character of Zend Url?

I use Zend URL view helper for building my urls. Everythings works exactly as I'd like to, except one thing: The character used for replacing spaces in the url is a plus (+). I'd like it to be a 'min' (-). How can I change this?
Example:
Now: /nl/nieuws/bericht/3/title/nieuwe**+affiches
Wish: /nl/nieuws/bericht/3/title/nieuwe-**affiches
Thanks in advcance!
This isn't in the documentation anywhere, but it appears that the Zend URL view helper can take a parameter in it's $urlOptions array called chainNameSeparator. No guarantee that's what you're looking for, but trying playing with that and see if it changes anything.
This is likely happening because, by default, Zend_View_Helper_Url will urlencode() what you send it, which would translate spaces into +. My suggestion to you would be to create a new view helper for the type of URL in your code that needs the special inflection.
Something like:
class Default_View_Helper_SpecialUrl extends Zend_View_Helper_Abstract
{
public function specialUrl(array $opts = array(), $name = null, $reset = false, $encode = true)
{
if (!empty($opts['whatever'])) {
$opts['whatever'] = str_replace(' ', '-', $opts['whatever']);
}
$router = Zend_Controller_Front::getInstance()->getRouter();
return $router->assemble($opts, $name, $reset, $encode);
}
}
This way the spaces are changed for whatever necessary route parameters before URL encoding happens by the router.