The error I am getting is
file: "/var/www/html/goalline/swiftmailer333/Swift.php" line: 32
message: "Cannot redeclare class Swift" type:
"Symfony\Component\Debug\Exception\FatalErrorException"
I have a need to remove Swift from Laravel as it conflicts with functions form a legacy application that my Laravel app needs to call.
How can I do this? Whether I should is irrelevant I have to use those functions from the legacy application.
I've tried commenting
'Mail' => 'Illuminate\Support\Facades\Mail',
and 'Illuminate\Mail\MailServiceProvider' but that didn't work.
You'll have to namespace your Swift class:
<?php
namespace YourApp;
class Swift {
}
Then use it this way:
$swift = new YourApp\Swift;
Another possibility is to create a nasty hack to remove it from your Laravel installation, but to do that you'll have to create a repository of your own and use your repository in your composer.json file:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/yourusername/swiftmailer"
}
],
"require": {
"swiftmailer/swiftmailer": "dev-master"
}
}
Your repository can pretty much be a copy of swiftmailer's which you basically remove every file except the composer.json.
Related
I have a project, and I need some packages, so I reorganized the project to use PSR-4.
Here's my composer.json:
{
"name": "me/production",
"type": "project",
"authors": [
{
"name": "Me",
"email": "me#me.com"
}
],
"config": {
"platform": {
"php": "5.6.1"
}
},
"autoload": {
"psr-4": {
"API\\": "api/"
}
},
"require": {
"nesbot/carbon": "^2.25"
},
}
it doesn't work in my scripts. But, here's the real kicker: I do require_once __DIR__ . '/vendor/autoload.php'; in my php console, and it doesn't work either. I have triple and quadruple checked the path, the autoload is there.
What do I mean by "doesn't work"? the autoload requires successfully. It allows me to use libraries. BUT actual instantiations result in a
Class not found error.
Not only for my classes in the API namespace, which are namespaced in the top of the file and are exactly in the folder they're suppose to be, but I also CANNOT instantiate Carbon. I can use Carbon\Carbon but any attempt to instantiate will fail.
Interestingly, instantiation of \Carbon\Carbon directly does not fail.
What's going on? This is weird.
Thank you in advance.
EDIT: I tried redumping the autoloader, I also tried removing the vendor folder and reinstalling. All to no avail.
EDIT: May be worth mentioning I downgraded carbon to ^1.21 because carbon 2 doesnt support php 5.6. But it still doesn't work.
EDIT: It happens with my API namespace as well, here's an example using my implementation of the Instagram API:
use \API\Insta;
php > var_dump(new Insta);
PHP Fatal error: Class 'Insta' not found in php shell code on line 1
php > var_dump(new \API\Insta);
object(API\Insta)#3 (1) {
["ig_token"]=>
string(51) "A_VALID_TOKEN"
}
php >
EDIT: The problem solved itself, it has now mutated into one I care very little about: I can use everything but not in the php console. I am not sure what fixed it.
As you found out, nesbot/carbon, version 2.25 requires at least PHP v7.1.8.
Just having a use statement doesn't check anything, instead it creates a local alias that can be used. If you try to use something that does not exist, only then would it fail.
Please clarify that you have the following directory structure:
./composer.json
./composer.lock
./Api/Insta.php
and in the file Api/Insta.php:
namespace API; // this is your top namespace name
use Carbon/Carbon; // etc
class Insta { ... }
Having the namespace different to the directory name can lead to confusion.
There will also be the index.php/front-controller that pulls in the vendor/autoload.php file and presumably runs the framework.
I am trying to include guzzle http client from a vendor folder and using composer. Here is what I have tried so far.
Location of guzzle http client file vendor/guzzle/guzzle/src/Guzzle/Http/Client.php
In composer.json file I included
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"files":["vendor/guzzle/guzzle/src/Guzzle/Http/Client.php"],
"psr-4": {
"App\\": "app/"
}
},
The I ran the command composer dumpautoload.
In my controller I am trying to call an api end point like this
use GuzzleHttp\Client;
$client = new Client(); // this line gives error
$res = $client->get('https://api.fixer.io/latest?symbols=CZK,EURO');
The error is Class 'GuzzleHttp\Client' not found
What I am missing here, please help me. Thanks.
For a better file structure here is a screenshot of of the file location
Short Version: You're trying to instantiate a class that doesn't exist. Instantiate the right class and you'll be all set.
Long Version: You shouldn't need to do anything fancy with your composer.json to get Guzzle working. Guzzle adheres to a the PSR standard for autoloading, which means so long as Guzzle's pulled in via composer, you can instantiate Guzzle classes without worrying about autoloading.
Based on the file path you mentioned, it sounds like you're using Guzzle 3. Looking specifically at the class you're trying to include
namespace Guzzle\Http;
/*...*/
class Client extends AbstractHasDispatcher implements ClientInterface
{
/*...*/
}
The guzzle client class in Guzzle 3 is not GuzzleHttp\Client. Its name is Guzzle\Http\Client. So try either
$client = new \Guzzle\Http\Client;
or
use Guzzle\Http\Client;
$client = new Client;
and you should be all set.
We added PHPExcel to composer by adding the following
To repositories:
{
"type": "package",
"package": {
"name": "PHPOffice/PHPExcel",
"version": "1.9",
"source": {
"url": "https://github.com/PHPOffice/PHPExcel.git",
"type": "git",
"reference": "1.9"
},
"autoload": {
"psr-0": {
"PHPExcel": "src/"
}
}
}
To require:
"PHPOffice/PHPExcel": "1.9.*"
In our code:
use PHPExcel\IOFactory;
...
$file = $request->get('file');
$inputFileType = IOFactory::identify($file);
The error we get is:
Attempted to load class "IOFactory" from namespace "PHPExcel".
Did you forget a "use" statement for another namespace?
The namespace looks right (https://github.com/PHPOffice/PHPExcel/blob/1.9/src/PhpSpreadsheet/IOFactory.php).
Use of the 1.9 branch is not recommended. It isn't completely converted yet to use namespaces, and is subject to significant code change. Nor is it backward compatible with the official 1.8 branch, and the changes are not yet documented, and also subject to further major changes as we modify the code to take advantage of the newer features of PHP.
The official release branch is still 1.8
Just because the 1.8 branch exists on github, doesn't mean that it's working code. I store it there so that it's available for shared development, and as a security (rather than keeping it all on my development laptop) in case I get run over by a bus tomorrow.
I have not used 1.9. Glad to see that they are moving to namespaces. That said, you might be better off sticking with 1.8 just for stability.
In any event, 1.9 relies on psr-4. Try adding this to your composer.json file:
"autoload": {
"psr-4": {
"PHPExcel\\": "src/PhpSpreadsheet"
}
}
Then rebuilding the composer generated autoload.php file.
I have an ecommerce site that i am building for a client. This site had previously worked perfectly fine using procedural functions and curl to make the calls to Paypal. I download the Mailgun and Easypost API manual and installed manually. DOwn the road, I wanted to update the site to utilize PDO & OOP. I have done a fair job at getting the foundation laid. Now it is time to start making calls to the various API's.I installed everything using composer and currently run a dual autoloader. The composer autoload and then beneath it a custom autoload to load my classes. Now, when I call on the PayPal API, I get the following error:
Fatal error: Class 'Paypal\Rest\ApiContext' not found in /var/www/html/myla-dev/shoppingCartFinalize.php on line 18
I think what is happening is my autoloader is trying to load this rather than the composers autoloader. Here is where the autoloading is occurring:
init.php
require __DIR__.'/core/functions/general.php';
function autoLoader ($class) {
if (file_exists(__DIR__.'/core/classes/'.$class.'.php')) {
require __DIR__.'/core/classes/'.$class.'.php';
}
}
spl_autoload_register('autoLoader');
require __DIR__.'/vendor/autoload.php';
This file sits in project root directory and is then required at the top of every file.
File Structure
core
--classes
----Alert.php
----....
--functions
----general.php
vendor
--composer
--easypost
--guzzle
--mailgun
--symfony
--paypal
--autoload.php
index.php
init.php
...
composer.json
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/EasyPost/easypost-php"
}
],
"require": {
"php": ">=5.3.0",
"easypost/easypost-php": "dev-master",
"ext-curl": "*",
"ext-json": "*",
"paypal/rest-api-sdk-php":"*",
"mailgun/mailgun-php": "dev-master"
}
}
Any and all assistance is appreciated. If you feel like writing code, GREAT, but that is not what I am asking for. That is my job, but help with reworking to make it work would be awesome.
Thanks
It ended up being a simple syntax error. After I dumped and updated composer it still failed to work, so I just copied the code from the installation wiki. It worked so I composer their code to mine and I was missing a backslash in my call to the wiki. Thank you for your assistance though.
Is it possible to include a package that was not specifically designed for L4 in the framework?
If so, how is it done? I know I need to add the package to my composer.json which adds it to the vendor folder, but can I register it somehow in the providers array? are there any other steps necessary?
I would like to use the Google checkout package originally designed for Yii
Using third party composer packages with Laravel 4
When developers create composer packages, they should map the auto-loading using PSR-0 or PSR-4 standards. If this is not the case there can be issues loading the package in your Laravel application. The PSR-0 standard is:
{
"autoload": {
"psr-0": { "Acme": "src/" }
}
}
And the PSR-4 standard:
{
"autoload": {
"psr-4": { "Acme\\": "src/" }
}
}
Basically the above is a standard for telling composer where to look for name-spaced files. If you are not using your own namespaces you dont have to configure anything else.
SCENARIO 1
PSR-0 standard following packages (with autoload classmap) in Laravel
This is a simple one, and for example i will use the facebook php sdk, that can be found:
https://packagist.org/packages/facebook/php-sdk
Step 1:
Include the package in your composer.json file.
"require": {
"laravel/framework": "4.0.*",
"facebook/php-sdk": "dev-master"
}
Step 2:
run: composer update
Step 3:
Because the facebook package uses a class map its working out of the box, you can start using the package instantly. (The code example below comes straight from a normal view. Please keep your logic out from views in your production app.)
$facebook = new Facebook(array(
'appId' => 'secret',
'secret' => 'secret'
));
var_dump($facebook); // It works!
SCENARIO 2
For this example i will use a wrapper from the instagram php api. Here there need to be made some tweaks to get the package loaded. Lets give it a try!
The package can be found here:
https://packagist.org/packages/fishmarket/instaphp
Step 1:
Add to composer .json
"require": {
"laravel/framework": "4.0.*",
"fishmarket/instaphp": "dev-master"
}
Then you can update normally (composer update)
Next try to use the package like you did with the facebook package. Again, this is just code in a view.
$instagramconfig = array(
'client_id' => 'secret',
'client_secret'=> 'secret',
'access_token' => 'secret'
);
$api = Instaphp::Instance(null, $instagramconfig);
var_dump($api); // Epic fail!
If you try the above example you will get this error:
FatalErrorException: Error: Class 'Instaphp' not found in ...
So we need to fix this issue. To do this we can examine the instagram composer.json, that has its autoload diffrent than the facebook php sdk had.
"autoload": {
"psr-0": { "Instaphp": "." }
}
Compared to the facebook composer.json:
"autoload": {
"classmap": ["src"]
}
(Composer handles different kinds of autoloading, from files and class-maps to PSR. Take a look at your vendor/composer/ folder to see how its done.)
Now we will have to load the class, manually. Its easy, just add this (top of your controller, model or view):
use Instaphp\Instaphp;
composer dump-autoload, and it works!
step2 (optional)
Another method is (if you dont want to use the "use" statement, you can simply tell composer to look for the files straight from your code. Just change the Instance like so:
// reference the name-spaced class straight in the code
$api = Instaphp\Instaphp::Instance(null, $instagramconfig);
var_dump($api); // It works
However I suggest using the usestatement to make it clear to other developers (and your future self) what (external) classes/packages are used in the program.
SCENARIO 3
Here we use the Laravels built in IOC container to register service providers. Please note that some packages might not be suitable for this method. I will use the same Instagram package as in scenario 2.
Quick and dirty
If you don't care about design patterns and service providers you can bind a class like this:
App::bind('Instaphp', function($app)
{
return new Instaphp\Instaphp;
});
And you resolve it like this.
App::make('Instaphp');
Quick and dirty end
If you're working on a bigger project, and you make use of interfaces you should probably abstract the bindings further.
Step 1:
Create a folder inside your app folder, for example a 'providers' folder.
app/providers
Make sure Laravel auto-loads that folder, you can pass in some additional info to composer.json, like this:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/providers" // this was added
]
},
Now create a File inside the new folder called Instagram.php and place this inside:
<?php
use Illuminate\Support\ServiceProvider;
class InstagramServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind('Instaphp', function()
{
return new Instaphp\Instaphp;
});
}
}
Now run composer dump-autoload again, and you can use the package. Note that the instagram package has a final private function __construct(), this means you cannot use that package outside the original class without changing the construct method to public. I'm not saying this is a good practice, and i suggest to use the scenario 2, in the case of the instagram package.
Anyway, after this you can use the package like this:
$instagramInstance = App::make('Instaphp');
$instagramconfig = array(
'client_id' => 'secret',
'client_secret'=> 'secret',
'access_token' => 'secret'
);
$instagram = new $instagramInstance();
$userfeed = $instagram->Users->feed($instagramconfig);
var_dump($userfeed); // It works!
Add "tvr/googlecheckout": "dev-master" this to your composer.json.
Run composer install, then you can use the IoC container. Some code examples can be found in the official docs for Laravel 4: http://four.laravel.com/docs/ioc#basic-usage