Zend framework 2 Zend\config not found - php

I have an issue on Zf2 when i try to create an xml document, using :
$config = new Zend\Config\Config(array(), true);
i followed the official documentation here :
Zend framework 2 Zend\Config\writer
I'm sure zf2 is loader and i don't understand what happening there but.
My output is
Fatal error: Class 'XmlGenerator\Controller\Zend\Config\Config' not found in C:\wamp\www\myLink\module\XmlGenerator\src\XmlGenerator\Controller\XmlGeneratorController.php
if someone can explain please, i'm lost ! :p
Thanks in advance !!

You are having a namespacing problem.
You need to either include the Zend namespace with use Zend; after where you declare the name space or change your code to $config = new \Zend\Config\Config(array(), true);
PHP is looking for class in your current namespace so it is adding the current namespace to fill name of the class (in this case "XmlGenerator\Controller") which the autoloader uses to determine which directory to get the class from. Since the Zend code isn't in the same directory as your controller, the autoloader chokes and gives you the error.
You need to tell your code that you are also using the Zend namespace (via use) or that the class you are using is in the global namespace (prepending the \ to the class name)

Related

php / composer not loading interface

I've banged my head against the wall for 3/4 of a day now and just can't see the error of my ways.
I'm creating (or trying to!) a simple package that consists of a couple of classes and 1 interface. This is in github at https://github.com/dnorth98/victoropsnotifier
Basically though, there's the following directory structure:
victoropsnotifer
src
Signiant
VictorOpsNotifier
Transport.php
VictorOpsNotifier.php
Transport is very simple:
<?php
namespace Signiant\VictorOpsNotifer;
interface Transport
{
// must POST the $message to the VictorOps REST endpoint
public function send(Messages\Message $message);
}
and the beginning of VictorOpsNotifier is
<?php
namespace Signiant\VictorOpsNotifer;
use GuzzleHttp\Client;
class VictorOpsNotifer implements Transport
{
protected $endpoint_url;
:
:
The problem comes when I try to instantiate a new object using
<?php
require_once 'vendor/autoload.php';
use Signiant\VictorOpsNotifier\Messages\CustomMessage;
use Signiant\VictorOpsNotifier\VictorOpsNotifier;
$voConfig = ['routing_key' => 'test',
'endpoint_url' => 'https://goo'];
$voHandle = new VictorOpsNotifier($voConfig);
I get back
PHP Fatal error: Interface 'Signiant\VictorOpsNotifer\Transport' not found in /tmp/djn/tests/vendor/signiant/
victoropsnotifier/src/Signiant/VictorOpsNotifier/VictorOpsNotifier.php on line 8
PHP Stack trace:
PHP 1. {main}() /tmp/djn/tests/test.php:0
PHP 2. spl_autoload_call() /tmp/djn/tests/test.php:12
PHP 3. Composer\Autoload\ClassLoader->loadClass() /tmp/djn/tests/test.php:0
PHP 4. Composer\Autoload\includeFile() /tmp/djn/tests/vendor/composer/ClassLoader.php:301
PHP 5. include() /tmp/djn/tests/vendor/composer/ClassLoader.php:412
What on EARTH am I missing? Composer is finding the package ok from my github repo and everying is in the vendor folder and looks ok. It looks like the namespaces match...so for some reason, it's just not loading the Transport.php file containing the interface.
It seems to be just a typo:
namespace Signiant\VictorOpsNotifer;
^ no `i` in here
but
use Signiant\VictorOpsNotifier\VictorOpsNotifier;
^ but here it is
same thing with the class name.
Also, you're declaring namespace Signiant as src/, but it's really src/Signiant
By the way, there's no need to declare this package as psr-0, better to use psr-4 insetad. Not a big deal, just for conformity.
P.S. The strange thing it was complaining about interface, while it shouldn't have to until it hit the class, and it certainly must not hit the class while there was a typo.
P.P.S You can easily avoid those typo errors by using a proper IDE, PHPStorm, for example. It would highlight name of the class as missing as long as there wre typos (and i don't even start talking about autocompletion).
class VictorOpsNotifer implements \Signiant\VictorOpsNotifer\Transport{}
try add namespace before your interface.

Trouble with Namepaces and Class Loading

Im building a custom CMS and have setup an autoloader, and have adapted use of namespaces. For the most part things are loading properly, but in certain cases PHP reports that it cannot find the class, the class file has been included.
Once a file is included (using require), it should be instanced as well.
The parent controller is instanced, then the child controller attempts to instance a few of its own dependencies.
$this->auth = new \Modules\Auth\RT\Auth();
This will look for a file at /modules/auth/rt/auth.php, and it does and the class is instanced properly.
The namespace of Auth is:
namespace Modules\Auth\RT;
The auth class tried to load its own dependencies, a model in particular.
$this->auth_model = new Models\ModelAuth();
Here the file to be included is at /modules/auth/rt/models/modelauth.php
It is included successfully, but this is where PHP says I cannot find this class.
Fatal error: Class 'Modules\Auth\RT\ModelAuth' not found in /Users/richardtestani/Documents/ShopOpen-Master/shopopen/modules/auth/rt/auth.php on line 12
What would cause the class from not being instanced even though the file is included?
Thanks
Rich
try this:
$this->auth_model = new Modules\Auth\RT\Models\ModelAuth();
try this:
$this->auth_model = new \Modules\Auth\RT\Models\ModelAuth();
OR
$this->auth_model = new Models\ModelAuth();
when you are in this namespace \Modules\Auth\RT
There was a Missing \ , so the code trys to include the namespace twice;
FOR REAL ;)

Codeigniter Custom Libraries and Namespaces

I have been creating custom libraries for a project that i've been porting over into the CI framework and I ran into an issue where certain classes have identical names.
To circumvent this issue, I tried implementing namespaces to no avail. I've been doing research and I know in the past this may not have been possible but with the newer version of PHP, I was wondering if there was a way to do this or if I was doing it correctly.
CI Version: 2.1.4
PHP Version: 5.4.12
Here is a demo of my setup:
application/libraries/class1.php
<?
class class1{
public function __construct()
{
$CI =& get_instance();
$CI->load->library('foo/class2.php');
}
}
?>
application/libraries/foo/class2.php
<?
namespace foo
class class2{
function bar(){
}
}
?>
When I run my CI application, I will get the following error:
Non-existent class: class2
Thanks for any help.
From what I've found, if the library file doesn't have
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
as the first line of code it won't load the library.
But then the namespace declaration needs to be above that.
CodeIgniter was written for PHP4 whereas namespace is PHP5.
There's more information in this thread: Namespace in PHP CodeIgniter Framework
Codeigniter does not support namespaces in 2.x and 3.x, what I would usually do especially with 3rd party libraries is load them in manually. Using your example, I would do:
// you can still manually load in libraries like this
require_once(APPPATH.'libraries/foo/class2.php');
class class1 {
public function __construct()
{
$CI =& get_instance();
// instantiate the class2 and make it available for all of class1 methods
$this->class2 = new foo/class2();
}
}
Just because it's a framework doesn't prevent you from using core php functionality, most people forget that you can still do normal php methods to achieve the same results.
This issue arose in a personal project while attempting to use some third-party libraries.
To get around it (without modifying the source files), I made a "bootstrap" class that loaded and extended the core library:
<?php
require_once(APPPATH.'libraries/foo/class2.php');
class class2 extends foo\class2 {}
This "bootstrap" class can then be loaded and used as if it were the extended one:
$this->load->library("class2");
$this->class2->bar(); // same as foo\class2->bar();
The issue is that 'load' doesn't take into account namespaces as far as I know.
which means that load('foo/class2') will look for the folder 'foo' inside the libraries folder.
you include the files normaly, when you create a new object you use the 'foo/bar'.
I'm not if the load class supports that though, You might need to simply create a new object manually(which is what the load class does anyway, it includes the file and creates a new object).
I'll quote an answer from Alex.
I know I've answered this question before I just can't find where and don't know what to search. So here it is: Codeigniter can only load single php file libraries (excluding drivers which is a different thing entirely). To load this kindof library (namespaced) you have to use something like: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md (class example).
Let's call it Autoloader_psr4 and save it in libraries (modify the class declaration to match this name verbatim (e.g. Autoloader_psr4). Remove the namespace declaration in the class so it looks like: https://pastebin.com/NU8Rbp7Y
Let's also move all the files in src/randomorg/ or src/foo to just be in a folder in third_party called RandomOrg or foo e.g. application/third_party/RandomOrg or application/third_party/foo. Your folder should look like the contents here: https://github.com/defiant/randomorg/tree/master/src/randomorg
Usage:
$this->load->library('autoloader_psr4');
$this->autoloader_psr4->register();
$this->autoloader_psr4->addNamespace('RandomOrg', APPPATH . 'third_party/RandomOrg');
$random = new \RandomOrg\Client(); // or whatever...

Symfony 2.4 How to load an external class?

I want to add an external lib into my symfony 2 project. I use the 2.4 version. I have read many "how to" but all solution doesn't work with this version.
Do you tell me how I can do to add my class in my project ?
My class Html2Pdf:
<?php
class Html2Pdf
{
// Code ...
}
?>
Do you know anything about services?
If you want to use that YoutubeDownloader class in controllers, you have to define it as a service so you can call anywhere you want.
Open your services.yml in;
YourBundle/Resources/config/services.yml
parameters:
youtubeDownload: YourBundle/YourPathToClass
services:
bundlename.controllername.controller:
class: "%youtubeDownload%"
More information:
http://symfony.com/doc/current/cookbook/controller/service.html
You can call it in a class using \Html2Pdf as you can with any none namespaced class.
Update:
As you are using Symfony and Composer the classes and namespace will already mapped so you simply need to include it using the \Html2Pdf namespace. The \ is to signify that it is a namespace based at the root level rather than a relative namespace (in the same folder).
If you were not using composer or something with an autoloader then you would need to include the file somewhere in your stack (this can be in the current file or some kind of parent file that serves this one) using include_once('**path to file**/Html2Pdf.php'). You would then use it in the same way as you would when using Symfony/Composer with the \.
This works for me.
include_once $this->get('kernel')->getRootDir() . '/../path/to/Html2Pdt.php';
$aHtml2Pdt = new \Html2Pdt();
I think this is what #Qoop is trying to say to.
I hope it helps.

How to load a class in Zend Framework

I got a PHP library (PHP Markdown) in my library fold in an standard Zend Framework application. What is the best way to load the file and all it's classes to use in my models and controllers.
Structure:
library/phpMarkdown/markdown.php
Note:
PHP Markdown has a really ugly structure: It's only real "API" is a simple function, not a class. So the elegant was do not work for this exact case, but regarding the question the genearl solution the correctly named files/class is also "the right answer.
Edit
So much good input here, really not sure which answer I should accept! Thanks to you all!
The autoloader
Just instantiate the class and the autoloader should find it. If it doesn't you need to add the namespace and path.
If you have a class in the following tree (for exemple) : library/My/Tool.php
You will need to add this to your application.ini :
autoloaderNamespaces[] = "My_"
And then in your code you just call :
$tool = new My_Tool();
Edit :
in the file Tool.php you must follow the Zend Naming Conventions and have something like this :
<?php
class My_Tool {
}
For more informations see this : Zend Naming conventions
To keep it simple and just add that one file, you could put something like this in your Bootstrap.php:
protected function _initLoad(){
Zend_Loader::loadFile('markdown.php', '/../library');
}
I just copied markdown.php into the application library and put this little function in the bootstrap. You could also use Zend_Loader::loadClass(); if you want.

Categories