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.
Related
I have a file that i put in app\Classes\myVendor\dev_client_api.php. This file has a class in it:
class someClass{
//stuff
}
I want to use this class in a controller.
In my controller I have done the following:
namespace App\Classes\myVendor;
use dev_client_api;
class myController extends Controller
{
///stuff
public function processData(Request $request){
$client = new someClass($vars);
}
}
When i execute this page I get:
Class 'App\Classes\myVendor\Controller' not found
I have to admit I am not sure what exactly I am doing. Any help would be great.
I assume your Controllers are in Laravel's default App\Http\Controller directory.
namespace App\Classes\myVendor;
class someClass {
//stuff
}
namespace App\Http\Controllers;
use App\Classes\myVendor\someClass;
class myController extends Controller
{
///stuff
public function processData(Request $request){
$client = new someClass($vars);
}
}
I need an example of where to exactly create the file, to write to it, and how to use the functions declared in the trait. I use Laravel Framework 5.4.18
-I have not altered any folder in the framework, everything is where it corresponds-
From already thank you very much.
I have Create a Traits directory in my Http directory with a Trait called BrandsTrait.php
and use it like:
use App\Http\Traits\BrandsTrait;
class YourController extends Controller {
use BrandsTrait;
public function addProduct() {
//$brands = Brand::all();
// $brands = $this->BrandsTrait(); // this is wrong
$brands = $this->brandsAll();
}
}
Here is my BrandsTrait.php
<?php
namespace App\Http\Traits;
use App\Brand;
trait BrandsTrait {
public function brandsAll() {
// Get all the brands from the Brands Table.
$brands = Brand::all();
return $brands;
}
}
Note: Just like a normal function written in a certain namespace, you can use traits as well
Trait description:
Traits are a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way which reduces complexity and avoids the typical problems associated with multiple inheritance and Mixins.
The solution
Make a directory in your App, named Traits
Create your own trait in Traits directory ( file: Sample.php ):
<?php
namespace App\Traits;
trait Sample
{
function testMethod()
{
echo 'test method';
}
}
Then use it in your own controller:
<?php
namespace App\Http\Controllers;
use App\Traits\Sample;
class MyController {
use Sample;
}
Now the MyController class has the testMethod method inside.
You can change the behavior of trait methods by overriding them it in MyController class:
<?php
namespace App\Http\Controllers;
use App\Traits\Sample;
class MyController {
use Sample;
function testMethod()
{
echo 'new test method';
}
}
Let's look at an example trait:
namespace App\Traits;
trait SampleTrait
{
public function addTwoNumbers($a,$b)
{
$c=$a+$b;
echo $c;
dd($this)
}
}
Then in another class, just import the trait and use the function with this as if that function was in the local scope of that class:
<?php
namespace App\ExampleCode;
use App\Traits\SampleTrait;
class JustAClass
{
use SampleTrait;
public function __construct()
{
$this->addTwoNumbers(5,10);
}
}
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
{
}
I have a base controller as follows
<?php
use Phalcon\Mvc\Controller;
class ControllerBase extends Controller {
public function initialize() {
}
// wrapper function for debug purposes.
public function pr($data = null) {
echo '<pre>';
print_r($data);
echo '</pre>';
}
}
and a users controller as follows
<?php
use Phalcon\Mvc\Model\Criteria;
use Phalcon\Paginator\Adapter\Model as Paginator;
use Phalcon\Mvc\View;
class UsersController extends ControllerBase {
public function initialize() {
// initialize parent, here ControllerBase.
parent::initialize();
}
public function loginAction() {
// disable the main layout.
$this->view->disableLevel(View::LEVEL_MAIN_LAYOUT);
// disable the controller layout.
$this->view->disableLevel(View::LEVEL_LAYOUT);
}
.
.
.
.
other functions...
}
i was wondering if i could call all the required phalcon classes in base controller and extend then to all the child classes so that i dont need to call them individually on each controller.
in otherwords, can i add the below code
use Phalcon\Mvc\Model\Criteria;
use Phalcon\Paginator\Adapter\Model as Paginator;
use Phalcon\Mvc\View;
only in the base controller and acces them in other controllers. I tried putting them base controller but it gave error : Class not found.
Is this the right way or is there something wrong in my approach...please help.
If I understand your question correctly the answer is NO.
Namespaces are language feature and works this way. The use Phalcon\Mvc\Model\Criteria only declares that you'll use Criteria class from Phalcon\Mvc\Model\ namespace. So in your code you can write new Criteria() to create object instead of using its' full name new \Phalcon\Mvc\Model\Criteria().
You must declare each class in every file which instantiates object of that class so autoloader will know in which file given class exists.
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.