I am relatively new to Zend as I am working with Apigility.
When I try to include classes from external files, which are part of another MVC project, files are read, but creating instances returns an error.
If I use an include/require function class_exists return true, but still I can't create objects, while using one of the autoloading procedures from Zend_Loader gives the error "class *** not found" (class_exists return false in this case) and prints on screen the entire content of the file.
It's not due to my MVC, because I got the same problem including a class created on the fly.
And it isn't a match problem.
Any ideas?
EDIT - As I am trying to load class User from function getServiceConfig() in Module.php of an Apigility application named 'Example'
// Zend\Loader\StandardAutoloader namespace is stated at the beginning and it is working
$loader = new StandardAutoloader();
$loader->registerPrefix('local', '/home/mylocal/class/local');
$loader->autoload('local_User');
$loader->check = class_exists('User'); // states true and is listed in get_declared_classes()
return new User(); // returns the error: Class 'Example\User' not found in /home/mylocal/apigility/module/Example/src/Example/Module.php on line *
The same code works correctly if used in the index.php file of Apigility public folder where there is no interference from Example namespace.
Related
I have an application running in CakePHP 3 and have installed my packages via Composer.
Most recently I added phpspec/php-diff (https://packagist.org/packages/phpspec/php-diff) and ran composer update. It has put the files, as expected, in vendor/phpspec/php-diff/
I can instantiate the class in one of my CakePHP Controllers like this:
// src/Controller/UrlsController.php
// ...
use Diff;
public function test()
{
$diff = new Diff(foo, bar);
// This works
}
However, the documentation for this package gives this as an example on https://github.com/chrisboulton/php-diff/blob/master/example/example.php#L43 which comes after instantiating Diff (as done in test() above).
require_once dirname(__FILE__).'/../lib/Diff/Renderer/Html/Inline.php';
$renderer = new Diff_Renderer_Html_Inline;
echo $diff->render($renderer);
Obviously the require_once statement doesn't work because that's not where Inline.php lives in Composers hierarchy.
So how do you instantiate new Diff_Renderer_Html_Inline? If I just use it like this it errors saying
Class 'App\Controller\Diff_Renderer_Html_Inline' not found
Another workaround I thought may be to change the path in require_once so it points to it's location in vendor/. But surely there is a better solution?
If you're trying to refer to a class from within another namespace you need to refer to it using its fully qualified name e.g.
new \Diff_Renderer_Html_Inline;
Or add a use Diff_Renderer_Html_Inline after the namespace declaration to be able to do : new Diff_Renderer_Html_Inline
I downloaded the PHP Amazon MWS Reports Client Library from here:
https://developer.amazonservices.com/gp/mws/api.html/182-5103998-0984662?ie=UTF8&group=bde§ion=reports&version=latest
and I was trying to get it to work but it looks like the library is not complete out of the box or there is something that I don't fully understand. For example in the samples folder there are sample functions that should let you get up to speed in no time however when you run any of them, PHP complains about missing classes. Lets take at one of the top lines of one of them:
$service = new MarketplaceWebService_Client(
'xyz',
'xyz',
$config,
'xyz',
'1.0');
So it is instancing the MarketplaceWebService_Client however that class is neither attached to this file nor nowhere to be found inside of it. After a quick search I found that the function exist under the following hierarchy:
MarketplaceWebService/Client.php
Can you see the resemblance to the class name? How is that supposed to work? Should I add all of those files using require_once or there should be any mechanism that loads them automatically?
Another one: class MarketplaceWebService_Model_GetReportListRequest exist under
MarketplaceWebService/Model/GetReportListRequest.php
I know that I could create an __autoload function and simply attach those classes dynamically but is this what the author had in mind?
PHP has an autoload capability which enables a function to be called if a required class does not exist at runtime. This capability allows the script to go and produce the missing class, normally by including a file which contains it.
Here's an example adapted from the PHP manual.
// Your missing class is called MarketplaceWebService_Client
// The code for this class is in MarketplaceWebService/Client.php
// define a function that will be called when a class does not yet exist
function my_autoloader($class) {
// implement the rules to convert the class into the file naming convention
$path = str_replace('_', '/', $class) . 'php';
// if there is a match, then include it now
if(file_exists($path)) {
include_once $path;
}
}
// tell PHP about the autoload function
spl_autoload_register('my_autoloader');
You may need to tweak the above example to fit your specific code and folder structure.
I can't speak to the PHP client library, but the C# library is complete out of the box and compiles from the start. The MWS team has a dedicated contact us page for these type of issues. They are willing to work with you through your issues and get you moving. You do have to log in with your seller credentials to access this page. Give it a try.
https://sellercentral.amazon.com/gp/mws/contactus.html
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 ;)
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...
This is a very basic question but I can't figure it out.
I have a class that could be named myClass.php, this is a standalone PHP script that contains a standard object definition like this:
<?php
class myClass
{
public function myFunction($param1, $param2){
return $param1*$param2;
}
}
All I want to do is to be able to call to this class from a model, this is from App/Models/MyModel.php be able to simply do $myClass = new MyClass();
Where should I store myClass.php in the file structure and how can I make it visible for MyModel?
Thanks!
You'll note that you have a 'vendors' directory inside the root (ie, on the same level as the 'app' folder). This is for placing non-CakePHP related files that are shared across applications. You also have an 'app/Vendor' directory, which is for storing non-CakePHP files that are specific to that one app.
So, it should go in one of these two directories - most likely, in app/Vendor.
There's a little bit to know about loading vendor files - you can read the details here.
In your case, you probably just need:
App::uses('myClass', 'Vendor');