I am using PHP ActiveRecord with my small MVC framework thtat includes an autoloader. In my controller I access the model Pub::find(64) for example.
My problem is that Pub::find(64) is inheritating the namespace of the controller and I get the error
Fatal error: Class 'App\Controllers\Pub' not found in /home/i554246/public_html/mvc/App/Controllers/Index.php on line 27
Pub is the Module name. The file get included ok. I can solve this issue by appending \Pub::find(64) but this is not really intuitive for new people on the project.
Is there a way to stop the namespace appending for the Pub::find(64) without altering that line?
Index Controller
namespace App\Controllers;
class Index extends \Core\Controller
{
protected
$title = 'Home'
;
/**
* Default action
*/
public function index()
{
// Pass the data to the view to display it
$this->view->set('testdb', \Pub::find(64));
}
}
App.php
/**
* Class autoloader
* #param $className
* #see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
*/
public function autoload($className)
{
preg_match('/(^.+\\\)?([^\\\]+)$/', ltrim($className, '\\'), $match);
//Build namespace Autoloading
$file = str_replace('\\', '/', $match[1]) . str_replace('_', '/', $match[2]) . '.php';
//Build Model path
$model = 'App/Models/' . $match[2] . '.php';
if ( is_file($file) ) {
require $file;
}elseif ( is_file($model) ) {
require $model;
}
}
Models/Pub.php
class Pub extends ActiveRecord\Model
{
}
It seems you don't understand namespaces.
Since you are using namespace App\Controllers, the global namespace is denoted with \.
So if you don't want to use fully-qualified name \Pub you have to put use declaration below the namespace, eg:
namespace App\Controllers;
use Pub;
PS: It's a good practice to put your models in a namespace too.
Related
I have class that I have set up like this:
use MVC\Model;
use \Firebase\JWT\JWT;
class ModelsAuth extends Model {
In my ModelsAuth class, I have this member function:
public function validateToken($token) {
}
I am using this to autoload my classes:
// autoload class
function autoload($class) {
// set file class
$file = SYSTEM . str_replace('\\', '/', $class) . '.php';
if (file_exists($file))
require_once $file;
else
throw new Exception(sprintf('Class { %s } Not Found!', $class));
}
// set autoload function
spl_autoload_register('autoload');
Is it possible to call this class and function from outside the class?
I have tried:
$authorization = new \MVC\Model\ModelsAuth();
$authorization->validateToken($token);
and
$authorization = MVC\Model\ModelsAuth::validateToken($token);
Both return a class not found error.
Any thoughts on what I might be doing wrong with this approach?
You have not declared a namespace for your class, so it's not clear that it will exist as MVC\Model\ModelsAuth and it's probably just going into the root namespace as \ModelsAuth. You probably want something like this:
namespace MVC\Model;
class ModelsAuth extends \MVC\Model {
...
}
Which can also be specified as:
namespace MVC\Model;
use MVC\Model;
class ModelsAuth extends Model {
...
}
I'm not fond of either of these options however, because then you've got a base class named \MVC\Model and a namespace named \MVC\Model, which is somewhat confusing. I'd recommend putting your base class as an abstract into the \MVC\Model namespace, in a file named MVC/Model/AbstractModel.php like this:
namespace MVC\Model;
abstract class AbstractModel {
...
}
And then your model in a file name MVC/Model/MyModel.php like this:
namespace MVC\Model;
class MyModel extends AbstractModel {
...
}
This way, all your models are in the same namespace and the same directory.
Also, if you use a PSR-4 autoloader then most of these sorts of issues will go away.
I have this folder structure for mvc:
application
-----------catalog
------------------controller
----------------------------IndexContoller.php
------------------model
----------------------------IndexModel.php
------------------view
------------------language
-----------admin
------------------controller
------------------model
------------------view
------------------language
core
------Controller.php
public
------Index.php
vendor
....
In index.php I have:
define('DS', DIRECTORY_SEPARATOR, true);
define('BASE_PATH', __DIR__ . DS, TRUE);
//Show errors
//===================================
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
define('ABSPATHS', preg_replace('/\\\/', '/', dirname(dirname(__FILE__))));
$abspath = preg_replace('/\\\/', '/', dirname(__FILE__));
require '../vendor/autoload.php';
//Upadte
$templates = new League\Plates\Engine(Config::get('PATH_VIEW'));
and autoload using composer PSR4 like this :
"autoload": {
"psr-4": { "Application\\": "application/","Application\\Core\\": "application/core/","Application\\Catalog\\Model\\": "application/catalog/model/"}
}
}
Now in Core Controller I have:
namespace Application\Core;
class Controller
{
// public $templates;
/**
* Construct the (base) controller. This happens when a real controller is constructed, like in
* the constructor of IndexController when it says: parent::__construct();
*/
public function __construct()
{
$this->Language = new Language();
}
}
In controller IndexController I have:
namespace Application\Catalog\Controller;
use Application\Core\Controller as Controller;
class IndexController extends Controller
{
/**
* Construct this object by extending the basic Controller class
*/
public function __construct()
{
parent::__construct();
}
/**
* Handles what happens when user moves to URL/index/index - or - as this is the default controller, also
* when user moves to /index or enter your application at base level
*/
public function index()
{
echo $templates->render('index/index', ['name' => 'Jonathan']);
}
}
In Action i see this error and autoload not loading class in controller:
Notice: Undefined variable: templates in /Applications/XAMPP/xamppfiles/htdocs/cms/application/catalog/controller/IndexController.php on line 23
How do can i fix this error?
The error states that Application\Core\League\Plates\Engine can not be found. According to your autoload definition Application\Core is located at application/core but according to you directory structure you supplied that file doesn't exists. You need to ensure the file you're trying to load exists where you've said it is.
As a side note you're using composer's PSR-4 autoload functionality but you aren't conforming to PSR-4
You're not explicitly listing vendor folder contents, but I suppose you installed the package https://github.com/thephpleague/plates/blob/master/composer.json through composer... then:
How about placing in Controller :
/Applications/XAMPP/xamppfiles/htdocs/cms/application/core/Controller.php
on top the line:
use League\Plates\Engine;
Also:
"autoload": {
"psr-4": { "Application\\": "application/","Application\\Core\\": "application/core/","Application\\Catalog\\Model\\": "application/catalog/model/"}
}
}
is too much...
The following should be enough:
autoload": {
"psr-4": {
"Application\\": "application/"
}
}
Then add directives like (when needed) in your classes:
use Application\Catalog\Model\...
EDIT
Var $templates is not accessible within IndexController, try this:
remove form index.php
$templates = new League\Plates\Engine(Config::get('PATH_VIEW'));
and edit IndexController as follows:
namespace Application\Catalog\Controller;
use Application\Core\Controller as Controller;
use League\Plates\Engine;
class IndexController extends Controller
{
/**
* Construct this object by extending the basic Controller class
*/
public function __construct()
{
parent::__construct();
}
/**
* Handles what happens when user moves to URL/index/index - or - as this is the default controller, also
* when user moves to /index or enter your application at base level
*/
public function index()
{
$templates = new Engine(Config::get('PATH_VIEW'));
echo $templates->render('index/index', ['name' => 'Jonathan']);
}
}
But since I suppose you'll need to use $templates in more controllers you should define
protected $templates = new League\Plates\Engine(Config::get('PATH_VIEW'));
in parent class Controller and access to it through
$this->templates
in descendants...
I create module and want use NuSoap.php file.
bpay
- src
-- Controller
--- BpayController.php
-- Lib
--- NuSoap.php
BpayController.php :
<?php
namespace Drupal\bpay\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\bpay\Lib\nusoap;
class BpayController extends ControllerBase {
private $client;
public function new() {
\Drupal::service('page_cache_kill_switch')->trigger();
$client = new nusoap_client('https://example.org/pgw?wsdl');
.
.
.
return $build;
}
}
NuSoap.php :
<?php
namespace Drupal\bpay\Lib;
.
.
.
When I run page, Show this error:
The website encountered an unexpected error. Please try again later. Error: Class 'Drupal\bpay\Controller\nusoap_client' not found in Drupal\bpay\Controller\BpayController->new() (line 26 of modules\bpay\src\Controller\BpayController.php).
How can I fix this error ?
Hope it will work fine,
I am assuming your class loader is working fine.
Class is defined as same name nusoap_client
Change this to:
use Drupal\bpay\Lib\nusoap;
This:
use Drupal\bpay\Lib\nusoap_client as nusoap_client;
I am writing a helper method to read and convert a xml data into json. I followed the steps below
1) Created file
app/helper/commonHelper.php
and added following code to it.
<?php
function xmlToArray($xml, $options = array()) {
// the entire code here
}
2) Created a file under
app/providers/HelperCommonsProvider.php
and following code
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class HelperCommonsProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
require base_path().'/app/Helpers/CommonHelper.php';
}
}
Now when I call xmlToArray() in the controller like
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use Tymon\JWTAuth\Facades\JWTAuth;
use Illuminate\Support\Facades\Config;
use Log as EventLogger;
class UsersController extends Controller {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index() {
echo "You are in the index function";
$file = Config::get('constants.constants.userdirectory');
$file = $file . '/' . 71 . '/' . 71 . '.xml' ;
$xmlloaded = simplexml_load_file($file);
$returnvalues = xmlToArray($xmlloaded, array('alwaysArray'));
echo json_encode($returnvalues);
die;
//
}
}
This throws an exception
Fatal error: Cannot redeclare xmlToArray() (previously declared in D:\work\HC\hcserver\app\Helpers\CommonHelper.php:3) in
D:\work\HC\hcserver\app\Helpers\CommonHelper.php on line 79
PHP Fatal error: Uncaught exception 'Illuminate\Contracts\Container\BindingResolutionException' with
message 'Target [Illuminate\Contracts\Debug\ExceptionHandler] is not
instantiable.' in
D:\work\HC\hcserver\vendor\laravel\framework\src\Illuminate\Container\Container.php:748
Please tell me what am I doing wrong here?
UPDATED: Entire content inside CommonHelper.php -> http://pastebin.com/GuQGYnJP
you should change name from
xmlToArray
to
xmlToArrayCustom
Reason: its global function which make sense to laravel and php.
because this method name is used by PHP Library and cannot be redaclared with the same name.
I am trying to create an ACL component as a service, for a multi-module PhalconPHP application. When I call the ACL component from the Controller Base, I am getting an error that I can't re-declare the ACL class.
Any ideas how to fix it, and understand the logic of why it is re-initialized again?
Fatal error: Cannot declare class X\Acl\Acl because the name is already in use in C:\xampp\htdocs\x\app\common\Acl\Acl.php on line 12
Update:
If I changed everything to "Pacl" then it works. I assume there might be a mixup with the PhalconPHP namespace. I am either not using the namespaces properly, or there's a bug in PhalconPHP 2.1 Beta 2.
/app/common/Acl/Acl.php
namespace X\Acl;
use Phalcon\Mvc\User\Component;
use Phalcon\Acl;
use Phalcon\Acl\Role as AclRole;
use Phalcon\Acl\Resource as AclResource;
/*
* ACL component
*/
class Acl extends Component {
private function initialize() {
}
public function isAllowed() {
die('called');
}
}
/app/front/controllers/ControllerBase.php
namespace X\Front\Controllers;
use Phalcon\Session as Session;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
class ControllerBase extends Controller {
public function beforeExecuteRoute(Dispatcher $dispatcher) {
//$this->acl = $this->getDI()->get("acl");
var_dump($this->acl->isAllowed()); //same behavior in both case
}
}
/app/front/Module.php
namespace X\Front;
use Phalcon\DiInterface;
use Phalcon\Mvc\Dispatcher;
use X\Acl\Acl as Acl;
class Module {
public function registerAutoloaders() {
$loader = new \Phalcon\Loader();
$loader->registerNamespaces(array(
'X\Front\Controllers' => __DIR__ . '/controllers/',
'X\Front' => __DIR__,
'X' => __DIR__ . '/../common/'
));
$loader->register();
}
public function registerServices(DiInterface $di) {
$di['acl'] = function() {
return new Acl();
};
}
}
This is not Phalcon issue. Look closely at your code:
namespace X\Acl;
use Phalcon\Acl;
class Acl extends ... {
}
What Acl interpreter should use? X\Acl\Acl or Phalcon\Acl?
The same error you get for example for the following code
namespace My\Awesome\Ns;
use Some\Name; # Name 1
class Name # Name 2
{
}