PHP - How to get httpful phar to work - php

From http://phphttpclient.com I followed "Install option 1" and the first "quick snippet".
I end up with the following, with Request undefined.
Additionally, and perhaps relatedly, I am confused by the fact that one of the code samples says "$response = Request::get" and another says "$response = \Httpful\Request::get". Is the latter valid PHP?
I have PHP 5.6.7.
What am I doing wrong?

Yes, \Httpful\Request::get() is valid PHP. It tells PHP that you're looking for the class Request in the namespace Httpful. More on namespaces: http://php.net/manual/en/language.namespaces.php
The reason you can call \Httpful\Request::get(), but can't call Request::get() is namespace related. In your index.php, you're not defining a namespace. Therefor, PHP just looks for a class Request in the global space (when calling Request::get()). PHP does not check if there's a Request class in another namespace.
You can use (import) a class, that will prevent you from having to type the entire namespace everytime you want to use the Request class:
<?php
use Httpful\Request;
$request = Request::get()
# you can also rename the class if you have multiple Request classes
use Httpful\Request as Banana;
$request = Banana::get()
More on that subject: http://php.net/manual/en/language.namespaces.importing.php

I just followed the 'quick-hack' install suggested by the author and got the same result. I then used the fully qualified namespace and got it working.
as :
$response = \Httpful\Request::get($uri)->send(); // qualified namespace here
I'll stick to the hack while i kick the tires, then if i adopt the lib, i'll go the composer route (much much better imo).

Related

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.

Autoloading package that contains Class of same name as imported class

I have a project that includes a PHP file that defines a class named Response and I'm auto-loading Guzzle via composer (which also defines it's own Response class)
The question is do I run the risk that PHP might get confused as to which Response class it should use? If I use Response by itself I don't run the risk that it will somehow fetch the Guzzle class unless I do a use statement right?
I think it's fine unless I do the use statement but I just wanna be sure.
You don't have any risk of conflicts, that's why PHP Namespaces exist!
Although the short name of both classes are the same, their FQCN (Fully Qualified Class Name) are different, so there's no chance of getting confused.
Guzzle's Response class is:
\Guzzle\Http\Message\Response
Your class would be something like:
\MyApp\Response
(or just \Response if you didn't set a namespace for it, which is a very bad practise!)
You can use either of them in your classes, or even both, as long as you set an alias for one of them:
use \MyApp\Response;
use \Guzzle\Http\Message\Response as GuzzleResponse;
// ...
$myResponse = new Response();
$guzzleResponse = new GuzzleResponse();
As long as the classes got individual namespaces.
Composer (and its autolaoder) will resolve the namespace with the classname.
So if you use your own class ("Class1") and the foreign class ("Class2") with the same classname ("Classname") with different namespaces e.g.
namespace \Me\MyPackage\Classname
namespace \Guzzle\Classname
you will be fine. If you wanna create an instance of one of the classes just type the full qualified namespace e.g.
$var1 = new \Me\MyPackage\Classname();

In yii2, how do I autoload my own PHP classes?

Inside my Controller I want a function to use mpdf e.g.
public function actionPdf(){
include("MPDF57/mpdf.php");
$mpdf=new mPDF('c');
$mpdf->SetDisplayMode('fullpage');
$mpdf->WriteHTML("<h1>Hello World!</h1>");
$mpdf->Output('filename.pdf', 'F');
}
}
This does not work, and throws an error:
Class 'app\controllers\mPDF' not found
What should I do If I want to autoload the class
(a). Just for this Controller Action
(b). To make it usable everywhere just by using the use statement.
I know it has to do something with namespaces but don't know how do I define a namespace, and where do I place this MPDF57 folder and then make it accessible.
I also tried this :
$name = "MPDF57/mpdf.php";
spl_autoload_register(function ($name) {
var_dump($name);
});
But this didn't work either. throws the same error when I call my controller Action.
Here is the namespace declaration and use statements inside :
namespace app\controllers;
use Yii;
use app\models\Regs;
use app\models\Voters;
use app\models\RegsSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use \yii\web\Response;
use yii\helpers\Html;
use kartik\mpdf\Pdf;
Yii has already had autoloader, you do need nothing to load your class.
Just create your class with correct namespace and it will be loaded where are you using it only.
Namspace should represent real path to PHP file. PHP file name and class name should be same.
You should simply use mpdf/mpdf package :
Install it using composer :
composer require "mpdf/mpdf" ">=6.0.0"
Use it like this :
$mpdf = new \mPDF();
Or you can use a yii2 extension like this one : https://github.com/kartik-v/yii2-mpdf
I've faced such problems in one of my previous projects. I'm not good at PHP or Yii2 - so follow my guide on your own risk :)
When you you add use path\to\ExternalLibrary that means the interface is ready to use inside current class (e.g. CurrentController.php).
That means your application knows how to bring your path to it's stage.
E.g. use common\models\Post lets you directly to use Post class, as $posts = new Post;
So if your library contains only one file, just put is some "canonic" path. To common\models\ for example. So you can use it like any other model interface.
But for sake of your project put it on vendor folder. Then install a random library with composer. And observe which files are modified (1-3 generally). Also try to understand the modification logic. When you get sure that you've grasped everything, copy and paste these parts and change the paths, names, etc. for your library.
The best way, I think, is to make your library PSR-4 compatible and ship it as a PHP package. Thus, others can also benefit from your work.
There are lots of guides about making php packages.
http://sitepoint.com/starting-new-php-package-right-way/
https://knpuniversity.com/screencast/question-answer-day/create-composer-package
http://jessesnet.com/development-notes/2015/create-php-composer-package/
http://culttt.com/2014/03/12/build-php-package/
If you are planning to be a good PHP developer, I recommend to look up Josh Lockhart's "Modern PHP: New Features and Good Practices" book ( free pdfs are available :) ). That will help you to understand the fundamentals of OO PHP including namespaces, interfaces etc. So, you will be able to handle such problems in modern way.

'Services_Twilio' not found - Laravel

As far as I understand, I cannot simply use use Twilio to make it work. Thus, I tried require_once and require. The path should also be correct
I tried using require_once
$twilioDir = '../vendor/twilio/sdk/Services/Twilio.php';
require_once($twilioDir);
$client = new Services_Twilio($_ENV['TWILIO_ACCOUNT_SID'], $_ENV['TWILIO_AUTH_TOKEN']);
Class 'App\Http\Controllers\Services_Twilio' not found
What am I doing wrong?
Also, using require gave me error:
Cannot redeclare Services_Twilio_autoload() (previously declared in /var/www/Laravel/vendor/twilio/sdk/Services/Twilio.php:9)
I tried adding false to the line spl_autoload_register('Services_Twilio_autoload', false); in Twilio.php, but no luck
As far as I understand, I cannot simply use use Twilio to make it work.
Correct, because the class is named Services_Twilio.
use Services_Twilio; should do the trick.
Laravel handles autoloading for you. You shouldn't need to manually require the library unless Twilio has goofed something in their Composer setup.
I don't know who told you that you can't use Twilio but you can certainly use Twilio.
Grab the composer package - composer require aloha/twilio
Register the ServiceProvider in app.php like any other vendor: 'Aloha\Twilio\Support\Laravel\ServiceProvider', should be added to the providers array.
Register the facade to make life easy - in app.php add to the aliases array: 'Twilio' => 'Aloha\Twilio\Support\Laravel\Facade',
(optional) run php artisan vendor:publish so you can manage the assets that the vendor exposes to you.
Because we previously added the facade to the aliases array in our app.php we can correctly use Twilio; within our classes.
If you didn't do 3, then you need to reference the full namespace path; use Aloha\Twilio\Support\Laravel\Facade which will give you access to Twilio:: inside of that particular file.
Edit
I should note that you do not use Twilio from within the class, you must reference it outside of the class and before the class.
use Twilio; //Aloha\Twilio\Support\Laravel\Facade
class MyController {
/**
* Now you can use Twilio::whatever
*/
}
You have to import it at the top of the file.
I am not sure about the full path to the file but I am guessing it should be something like:
use Twilio\SDK\Services\Twilio
Update:
Follow the guide here:
https://github.com/aloha/laravel-twilio
The accepted answer didn't work for me.
Background: My code had worked for a while with use Services_Twilio;, but then I stopped using Twilio for months (or maybe more than a year), and then I was getting this error.
What ended up working was updating my code to say use Twilio\Rest\Client; instead and then create the client object via new Client($this->config['account_sid'], $this->config['auth_token']);.
This seems to be Twilio's newer way of doing things.
These docs helped.

Laravel 4 class not found and namespaces

In a Laravel 4 site I have installed a tag cloud library. In this library I wish to edit the return line of a function (I have simplified it here):
return "<span>
{$Variable}
</span>";
and make the $variable a link:
return "<span>
<a href='".Request::url()."/myroute/'>
{$variable}
</a>
</span>";
When I try to run the page I get the error:
Class 'Arg\Tagcloud\Request' not found
I thought that it might mean that the Request class is not visible within the tagcloud class and it has to do with namespaces.
On top of the tagcloud class file there are these lines:
<?php namespace Arg\Tagcloud;
use Illuminate\Support\Facades\Facade;
I have found this page (a list of laravel namespaces)
http://laravel.com/api/index.html
and I have used
use Illuminate\Routing;
or
use Illuminate;
I added them just below the above first two 'use' statements but I get the same error (class not found). Is it a matter of finding the right namespace or something else? Can anyone help? Thanks.
EDIT: I found this way of doing what I wanted without using
Request::url():
return "<span>
<a href='/mysitename/public/myroute/{$variable}'>
{$variable}
</a>
</span>";
Whenever you put your class in a namespace, any other class that you reference in that class assumes that it is also in that same namespace unless you tell it otherwise.
So, since you set your namespace to Arg\Tagcloud when you directly reference Request::url(), PHP thinks that you're telling it to use the Request class inside the Arg\Tagcloud namespace.
There's two solutions to this:
Solution 1
Add a \ in front of Request to tell PHP to use the global namespace, not the Arg\Tagcloud namespace.
e.g., <a href='".\Request::url()."/myroute/'>
Solution 2
use the class.
Just add use Request to the top of your class (under your namespace), this will let PHP know that you want to use this class, but it doesn't belong in the current namespace.
e.g.,
<?php namespace Arg\Tagcloud;
use Request;
When I try to run the page I get the error:
Class 'Arg\Tagcloud\Request' not found
It's because you are using the Request class from Arg\Tagcloud namespace and when you use Request::someMethod() framework things that Request class is under same namespace which is:
Arg\Tagcloud\Request
But, actually, Request class is under, Illuminate\Http namespace and that's why the error is being occurred. To overcome this problem you may use something like this:
\Request::someMethod();
Or you may use following at the top of your class:
use \Request;
You don't need to use use Illuminate\Request; because Request facade class is available in the global namespace (as an alias) which will resolve the Illuminate\Http\Request class. So, you can directly use Request::someMethod() in your code.

Categories