I am using Symfony3 for building a Twilio TaskRouter based application which is using the twilio-php library.
All the other components in Symfony use the PS-0 or PS-4 naming convention while the standard twilio-php library does not use the same, thus I am not directly able to use certain classes(in my case taskrouter) .
The class in question is Services_Twilio_TaskRouter_Worker_Capability which resides in twilio-php/sdk/Services/CapabilityTaskRouter.php.
Symfony expects the class to be in the directory vendor/twilio/sdk/Services/Twilio/TaskRouter/Worker/Capability directory, which it fails to find.
Is there a way to include vendor/twilio/sdk/Services/CapabilityTaskRouter.php
in a symfony class and extend the Services_Twilio_TaskRouter_Worker_Capability class?
You can install the lib in the vendor by running:
composer require twilio/sdk
and composer will add the lib to the vendor folder
and in you controller you will be able to call it like :
$sid = "ACXXXXXX"; // Your Account SID from www.twilio.com/user/account
$token = "YYYYYY"; // Your Auth Token from www.twilio.com/user/account
$client = new Services_Twilio($sid, $token);
$message = $client->account->messages->sendMessage(
'9991231234', // From a valid Twilio number
'8881231234', // Text this number
"Hello monkey!"
);
print_r($message->sid);
In my opinion it is possible. To keep the include logic separated from your project code, you should create a wrapper class that follows PSR-4 naming conventions, that simply extends the Twilio class.
<?php
namespace MyProject\Service;
require_once('path/to/twilio-php/sdk/Services/CapabilityTaskRouter.php');
class CapabilityTaskRouter extends \Services_Twilio_TaskRouter_Worker_Capability
{
}
This is the way, we did a lot of times to integrate libraries not following PSR auloading concepts into our projects.
Twilio employee here.
I went down the route of implementing a helper extension to https://github.com/fridolin-koch/VreshTwilioBundle and in that process discovered this was really a twilio-php helper library problem due to the naming conventions and the autoloading of these particular classes.
I intend to finish up the helper extension to VreshTwilioBundle, however, this is the PR that I have submitted that should keep you moving forward:
https://github.com/twilio/twilio-php/pull/288
Related
As i'm trying to install the Neo4jPHP library in codeigniter (v2.2.x), i'm having annoying issues regarding namespaces. I've been searching for 4 hours without success.
In short, there is a libraries directory in which Neo4jPHP must be copied. So in 'libraries/', there is a directory 'Everyman/Neo4j/', which contains all the Neo4j php classes.
Also, in the same 'libraries' directory, there is a class with an autoloader function, which aims at loading the Neo4j classes (which are in 'Everyman/Neo4j/').
Inside of 'libraries'
- libraries/
|-- Everyman/
|-- Neo4j/
|-- Client.php
|-- some_other_classes.php
|-- Neo4j.php
Then, somewhere in my code, in the global namespace, i try to instantiate the class client :
$client = new Client();
But i get the error Class 'Client' not found.
In the class client, the following namespace is specified : Everyman\Neo4j.
I'm must admit that i found 2 workarounds for this issue :
From the calling code, use the fully qualified name :
new Everyman\Neo4j\Client();
Or, in Client.php, remove the namespace.
In these 2 cases, it works. However, i would like to call the Client class with these 2 condition :
1. I don't want to modify anything from the Neo4jPhp library.
2. I really don't want to have to use the fully qualified name (Everyman\Neo4j\Client). I want to use "new Client()".
Do you guys have an idea how i could achieve this (yes, i don't have a very deep understanding of namespaces, and loaders).
In Neo4j.php (file with loader)
<?php
class Everyman{
public function __construct()
{
spl_autoload_register(array($this,'autoload'));
}
public function autoload($sClass){
$sLibPath = __DIR__.DIRECTORY_SEPARATOR;
//Below, i modified the instruction so that the class file
//can be found. However, the class is not found.
$sClassFile = 'Everyman'.DIRECTORY_SEPARATOR.'Neo4j'.str_replace('\\',DIRECTORY_SEPARATOR,$sClass).'.php';
$sClassPath = $sLibPath.$sClassFile;
if (file_exists($sClassPath)) {
require($sClassPath);
}
}
}
So that's it. I think i've given you all the information i have. If no one can help me, i'll have to use 'new Everyman\Ne4j\Client();' (which works).
It may seem stupid to ask for help, as i already have found 2 workarounds, but i really want to learn how to properly handle this issue (if possible).
Thanks.
It seems code like $client = new Everyman\Neo4j\Client('localhost', 7474); is the offical usage: https://github.com/jadell/neo4jphp#connection-test
So it is not work around.
I really don't want to have to use the fully qualified name (Everyman\Neo4j\Client). I want to use "new Client()".
I don't know what you really want. But then how about putting the code below in your code which you use Everyman\Neo4j\Client:
use Everyman\Neo4j\Client;
and
$client = new Client();
See http://php.net/manual/en/language.namespaces.importing.php
The supported way of installing neo4jphp is using Composer (https://getcomposer.org/). It is a good idea to learn how to use Composer, since a large number of PHP libraries can be installed using it. It also sets up the autoloading for you, so you don't have to worry about paths and namespaces yourself.
If you don't want to write new Everyman\Neo4j\Client() every time, you can put a use statement at the top of your script: use Everyman\Neo4j\Client; and then new Client();
Thank you for your answers.
For some reason, the 'use Everyman\Neo4j\Client' command didn't work, and i decided not to perform further inquiry into this issue.
So i decided to stick with the call to '$client = new Everyman\Neo4J\Client();', instead of trying to achieve '$client = new Client();'.
Thank you for your propositions.
Loïc.
I have a Laravel 5 application where I am building a custom OAuth interface. Everything is working well, but I cannot figure out how to reference the PECL OAuth package which is installed on the server. I'm sure its something pretty simple, but I can't figure it out and Google has oddly not been very helpful.
I have this line of code:
$oauth = new OAuth($ConsumerKey, $ConsumerSecret);
When outside of Laravel, it works perfectly, referencing the PHP package. But from within Laravel, it cannot find the class - because its not part of the application.
Can anyone help?
What's the exact error PHP is sending your way? I ask because pecl extensions make functions and classes available on a PHP level -- it shouldn't matter what userland level framework (Laravel, Symfony, etc.) you're using -- so long as the same PHP binary/web-server-extension is used, you'll have access to the pecl provided functions and classes.
My guess if you're trying to use the global class OAuth from within a namespaced file.
namespace App\Some\Namespace;
//...
$object = new OAuth;
When you do this, you're telling PHP you want the class OAuth in the same namespace. i.e., the class with the full name App\Some\Namespace\OAuth. To tell PHP you want the global level class OAuth, either refer to the class name with a namespace prefix character
$object = new \OAuth;
or import the global OAuth class with the use statement.
namespace App\Some\Namespace;
use OAuth; //confusingly, the `use` statement assumes a global namespace, no prefix needed
//...
$object = new OAuth;
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.
I'm making now things with php + Symfony2 framework, and I have the following code:
require_once("one_file.php");
require_once("another_file.php");
... and so on.
The problem is, how to "Symfonyze" these uncomfortable require sentences, and after, how to include these files in the Symfony2 package?
We've thought about two possibilities:
Include the file at /vendors directory of symfony, or
Include each class as a service.
If these classes reside inside bundle then you could use as below:
Suppose your bundle name is AcmeDemoBundle. Place this file inside Acme/DemoBundle/Model/
//one_file.php
namespace Acme/DemoBundle/Model;
class one_file {
...........
}
To use this file inside your controller or any other file:
Here for Acme/DemoBundle/Controller/UserController.php
namespace Acme/DemoBundle/Controller
use Acme/DemoBundle/Model/one_file
class UserController {
public $one_file=new one_file();
}
In php 5.3 onwards, namespaces has been introduced. You should probably look at namespaces and its uses in php documentation
You can follow the PSR-0 standard to let the autoloader handle this. See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md and http://getcomposer.org/doc/04-schema.md#psr-0 .
Or you could keep your files as is, and tell composer to require them each time : http://getcomposer.org/doc/04-schema.md#files
You have to make a folder in your acme folder like lib puts these files in lib folder then use this statement
use Acme\DemoBundle\lib\Abc; // its your class name
You want to follow these other answers, especially the approved one, but if you are using a third party library with tons of PHP files, you can do require_once(__DIR__.'/path/to/file.php') as a quick fix.
I have a file (an xmlrpc library for PHP) that I would like to use into a Symfony2 class (so inside a Symfony2 project).
I can't use autoloader because as written here
which is able [the autoloader] to load classes from files that
implement one of the following conventions:
1) The technical interoperability standards for PHP 5.3 namespaces and
class names;
2) The PEAR naming convention for classes.
If your classes and the third-party libraries you use for your project
follow these standards, the Symfony2 autoloader is the only autoloader
you will ever need.
the class that I'll go to use, didn't satisfies one of those requirements.
So if I can't autoload that file, since isn't possible (as I understand, but I can go wrong) to use require_once (or simply require) with namespace, what is the solution for this issue?
Assuming you have a file named xmlrpc.lib.php with the following content:
<?php
class XMLRPC_Server {
// ...
}
class XMLRPC_Request {
// ...
}
class XMLRPC_Response {
// ...
}
You can create an instance of MapClassLoader to handle it's autoloading:
// Create map autoloader
$mapLoader = new MapClassLoader(array(
'XMLRPC_Server' => __DIR__.'/../library/xmlrpc.lib.php',
'XMLRPC_Request' => __DIR__.'/../library/xmlrpc.lib.php',
'XMLRPC_Response' => __DIR__.'/../library/xmlrpc.lib.php',
));
// Register autoloader
$mapLoader->register();
When one of these classes will be auto-loaded, others will be auto-loaded too because they share the same PHP file.