How to make custom namespace from path, like in Yii 2 namespaces? - php

I found, that in Yii 2 there is an interesting namespace app. For example,
use app\assets\AppAsset;
There http://www.yiiframework.com/doc-2.0/guide-concept-autoloading.html I found info
When using the Basic Project Template, you may put your classes under
the top-level namespace app so that they can be autoloaded by Yii
without the need of defining a new alias. This is because #app is a
predefined alias, and a class name like app\components\MyClass can be
resolved into the class file AppBasePath/components/MyClass.php,
according to the algorithm just described.
Also I found http://www.yiiframework.com/doc-2.0/guide-concept-aliases.html#predefined-aliases
#app, the base path of the currently running application.
And, when I call
print_r(Yii::getAlias("#app"));die;
it's printing
/home/u1326jyq/domains/lifesim.biz/public_html/dev
Am I right or not, that namespace app is equal to /home/u1326jyq/domains/lifesim.biz/public_html/dev ?
But, if I trying to execute script like
use home\u1326jyq\domains\lifesim.biz\public_html\dev\assets\syntaxhighlighter\SyntaxhighlighterAsset;
SyntaxhighlighterAsset::register($this);
it's fails with 500 error.
Where is definition of the app namespace in Yii2 and how to define custom myCustomApp namespace, that will be equal to my path /home/u1326jyq/domains/lifesim.biz/public_html/dev, to using it with code like
use myCustomApp\assets\syntaxhighlighter\SyntaxhighlighterAsset;
that must be equal to code
define('__ROOT__', dirname(dirname(__FILE__)));
require_once(__ROOT__.'/assets/syntaxhighlighter/SyntaxhighlighterAsset');
?
Thank you very much!

Related

PHP - Fatal error: Uncaught Error: Class 'Contentful\Delivery\Client' not found [duplicate]

I am trying to call my model file from another folder. I have provided both of these file structure.
I am getting this error:
Uncaught Error: Class 'App\Models\Providers' not found in /Applications/XAMPP/xamppfiles/htdocs/pro/app/Scripts/Providers/1/Scrape.php:17
I am calling the model file from a script folder located :
app/Scripts/Providers/1/Scrape.php
In this class I have the below :
namespace App\Scripts\Providers\1;
use App\Models;
Model file is located :
app/Models/Providers.php
Within this file I have the below:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
I have not shared the full content that I have in both of these files. If you would like to see the full content of these files please let me know.
This is how the Scrape.php looks like
<?php
namespace App\Scripts\Providers\1;
use App\Models\Providers;
class Scrape {
public function __construct() {
$test = new \App\Models\Providers();
die(print_r($test, true));
}
}
$obj = new Scrape();
You can't have a namespace that starts with a number.
Namespaces follow the same basic rules for variable names:
A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores
(Emphasis mine).
Thus, your declaration
namespace App\Scripts\Providers\1
is basically invalid.
From that point forward, all bets are off.
First, change your namespace to a valid identifier (and I would advise choosing something more reasonable and recognizable than numbers, you can have descriptive names and there is simply no reason not to):
namespace App\Scripts\Providers\GroupWhatever
Logically, you'll have to rename the folder where this file resides. It used to be
app/Scripts/Providers/1/Scrape.php
so rename that directory to
app/Scripts/Providers/GroupWhatever/Scrape.php
(In both cases, replace GroupWhatever with something that makes sense for your application and domain).
From that point forward, if the class \App\Models\Providers exists at app/Models/Providers.php, it should work.
Important:
Another problem that there could exist, is that is not very clear what Scripts/Scrape.php is or how is it called.
This should work if you are executing Scrape.php from within Laravel, by calling a Laravel controller or console application.
If you are calling this script directly (e.g. by executing php app/Scripts/Providers/1/Scrape.php (or the corrected app/Scripts/Providers/GroupWhatever/Scrape.php) this simply won't work, since the autoloading logic is not run at all.
If you are executing your script manually, on top of the above changes you need to include composer autoload script, which is located at vendor/autoload.php.
Basically, add this line close to the top of your Scrape.php:
require_once dirname( __DIR__ ) . '/../../../vendor/autoload.php';
(I think I put the appropriate amount of go-up-one-dir path-segments, but you make sure it matches the correct path in your installation).
Once that is in place, the autoloader will be run, and classes will be found.
In your Scrape.php, change your namespace to:
<?php
namespace App\Scripts\Providers\p1;
From PHP manual comment,
namespace (even nested or sub-namespace) cannot be just a number, it
must start with a letter. For example, lets say you want to use
namespace for versioning of your packages or versioning of your API:
namespace Mynamespace\1; // Illegal
Instead use this: namespace
Mynamespace\v1; // OK

Trying to add a library to Symfony using composer

I am trying to add the following library (link) to my Symfony project using composer.
I have run
composer require jaggedsoft/php-binance-api
without a problem but I am getting the following error when loading the page.
Attempted to load class "API" from namespace "App\Controller\Binance".
Did you forget a "use" statement for another namespace?
public function index(){
require '../vendor/autoload.php';
$api = new Binance\API("<api key>","<secret>");
}
Now i am guessing that I need to add a use statement but I am a bit stuck on what it is that I need to add.
To reiterate what I suggested in the comments (options 1 and 3 below):
The namespace of your file - although not explicitly written in your post - is:
App\Controller
without any use statement, the new Binance\API(...) is interpreted as:
App\Controller\Binance\API
which is the concatenation of App\Controller (your namespace) and Binance\API (the classname used).
which of course is not what you want to use, since this is something you tried to include from the binance package. This also explains the error message
Attempted to load class API from namespace App\Controller\Binance. Did you forget a use statement for another namespace?
which is exactly what went wrong. PHP tried to load App\Controller\Binance\API which is class API from namespace App\Controller\Binance.
Now there are A few different ways to fix this:
add use Binance; in the header of your file, then you can use new Binance\API(...)
add use Binance\API; in the header of your file, then you can use new API(...)
don't add a use statement, then you can use new \Binance\APi(...)
add use Binance as Something; in the header of your file, then you can use new Something\API(...); (aliasing the parent namespace Binance as Something may resolve name collisions)
add use Binance\API as BinanceApi; in the header of your file, then you can use new BinanceApi(...);
You decided to use option 1. Which is preferable, if the class (API in this case) isn't very expressive or unique on its own - so is option 5. However, if you use more classes from the Binance namespace, option 1 is preferable.
Option 3 will always work (and might seem preferable if any of the other options seem overkill for some reason) - you can actually get by without any use statement at all, but it can get frustrating to read and write.
Overall, all options are viable and it comes to taste which one to use. Mixing those options may lead to confusion. Inside Symfony I've mostly seen option 2 with the occasional alias (use ... as ...;), especially when using DoctrineORM annotations or when extending some Class which has the same Class name but in a different namespace:
namespace [package1];
use [package2]\[ClassName] as Base[ClassName];
class [ClassName] extends Base[ClassName] { ... }
I hope this explanation helps. The php docs for namespaces are actually helpful, when you understand the core concept of namespaces.

How does name spacing works using PSR4 in laravel 5?

I am a novice laravel developer and I am trying to understand how namespacing works in here. So I was learning about the Repository pattern and decided to go ahead and implement it in my project.
So I created a directory called archive and then loaded it using PSR4 in my composer.json file like so:
"Archive\\": "archive/"
Now I created a Repositories folder in my archive folder where I will be creating all the repositories. And I am namespacing files in it like so:
namespace Archive\Repositories;
Which seems to working fine. Then I created a Contracts folder inside the Repositories folder which will hold all the interfaces to the implementations I am going to use like UserRepositoryInterface for example. And I am namespacing files in the Contracts folder like so:
namespace Archive\Repositories\Contracts;
Which is working fine too.
Now my doubt lies in the concrete implementations I am trying to make in the Repositories folder. Like for example there is a DbUserRepository which implements The UserRepositoryInterface in the Contracts folder.
Now since I am new to this I tried:
class DbUserRepository implements Contacts\UserRepositoryInterface
And it works just fine but then I thought I should use it on top of the file like so:
use Contacts\UserRepositoryInterface;
And I could just do:
class DbUserRepository implements UserRepositoryInterface
And it should work fine according to me but it gives me a class not found exception but when I do something like:
use Archive\Repositories\Contacts\UserRepositoryInterface;
It works fine now. But this is where I am blurry. Inside the DbUserRepository I am in the nampspace of Archive\Repositories already so why doesn't it just go on to look into the Contracts folder from there? Why do I need to specify the full this as use Archive\Repositories\Contacts\UserRepositoryInterface;
Why can't I just say:
use Contacts\UserRepositoryInterface;
I hope my question is not too confusing. Although my code is working now but I am blurry how namespacing works.
The rules are pretty simple:
All namespace and use statements always use fully qualified names (FQN), meaning they always start from the global namespace and are not relative to anything else. use Foo\Bar always means \Foo\Bar, no matter what namespace you're in.
All literal mentions of names inside the rest of the code are resolved relative to the current namespace and/or aliases established with use statements. new Foo, extends Foo and such either mean __NAMESPACE__\Foo, or whatever Foo you might have aliased in some use statement.
If you want to shorten names, you need to use use statements which use the FQN of the class, not relative to the current namespace.

include external lib in laravel?

how to include external lib in laravel ? for example twitteroauth.php.
no need oauth other packages. because i am converting Symfony code to Laravel. Thanks.
Class 'App\Controllers\Front\TwitterOAuth' not found
.
require_once base_path().'/vendor/twitter/twitteroauth.php';
$twitterOAuth = new TwitterOAuth('app_twitter_consumer_key', 'app_twitter_consumer_secret');
Likely you have a namespace problem, Laravel is looking for the class inside the 'App\Controllers\Front' namespace.
If the class is not namespaced, use
$twitterOAuth = new \TwitterOAuth('app_twitter_consumer_key', 'app_twitter_consumer_secret');
(note the backslash before the classname)
otherwise you need to refer to its namespace, something like \Twitter\TwitterOAuth or similar, but only by looking at the class file you can tell.
You could also create an alias for the class. Inside the app\config\app.php file search for the aliases array and add your class:
'Twitter' => 'TwitterOAuth' #(or whatever namespace it's in)
By the way, why not using a specific package? Have you looked on http://packagist.org to see if there's a Twitter OAuth package already adapted for Laravel? That would make things a lot easier.

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.

Categories