I've developed a small project on a machine, using CakePHP 3.0, and I need it to run on another machine. I've tried to install it on several other machines.
If I run the composer to install the CakePHP 3.0, then I copy my stuff to overwrite it, the project works. I've tried this on two machines and had no problem so far. If I don't run the composer, and just copy the stuff to the target machine, it gives me the following error. I've tried this on 3 machines, and every machine gives me this:
Fatal error: Class 'Locale' not found in /home/u113681897/public_html/vendor/cakephp/cakephp/src/I18n/I18n.php on line 229
Fatal error: Class 'Locale' not found in /home/u113681897/public_html/vendor/cakephp/cakephp/src/I18n/I18n.php on line 229
I've copied the whole project to this server to test.
I told you this because I thought it has something to do with my problem. The point is that I have to run this on a machine that is not mine, and I can't install composer on it. The /public_html/vendor/cakephp/cakephp/src/I18n/ has files related to internationalization and localization, but my project will never be translated, so a workaround to make the project ignore those files would be enough to solve my problem.
The following code is an excerpt from the (...)/I18n/I18n.php that might be relevant:
<?php
namespace Cake\I18n;
use Aura\Intl\FormatterLocator;
use Aura\Intl\PackageLocator;
use Aura\Intl\TranslatorFactory;
use Cake\I18n\Formatter\IcuFormatter;
use Cake\I18n\Formatter\SprintfFormatter;
use Locale;
class I18n {
// lots of code here
public static function defaultLocale() {
if (static::$_defaultLocale === null) {
static::$_defaultLocale = Locale::getDefault() ?: 'en_US';
// the line above is the Line 229
}
return static::$_defaultLocale;
}
// many code here too
}
I've checked that another file also tries to access this Locale class, but I don't know if there are other files trying to access it as well. Many files from everywhere inside the project tries to access methods from I18n.php. I need it running but I can't figure out how to make it run.
Any help will be greatly appreciated.
As I just found out, prior to CakePHP 3.0, the installation must be done by composer, as stated in the 3.0 migration guide:
CakePHP should be installed with Composer
Since CakePHP can no longer easily be installed via PEAR, or in a shared
directory, those options are no longer supported. Instead you should use
Composer to install CakePHP into your application.
So it won't run on regular free web hosting services.
Related
I am new to php and have just installed my first package via composer. I'm now trying to call a function from the package I installed as follows:
<?php
require_once 'vendor/autoload.php';
$value = 1;
$aws = AmazonGiftCode::make()->buyGiftCard($value);
echo $aws;
?>
But I get the following error:
PHP Fatal error: Uncaught Error: Class 'AmazonGiftCode' not found in
/public_html/php/test.php:4 Stack trace:
#0 {main} thrown in /public_html/php/test.php on line 4
Based on my (albeit limited) experience with other languages, I'm guessing I have to load the package that contains the class first. The package folder is in the same directory as the test.php file, in the subfolder vendor/kamerk22/AmazonGiftCode/. But I think this is where I don't know enough to troubleshoot it based on the information I could find.
Your directory structure should look like this.
test.php
composer.json
vendor
└───autoload.php
└───kamerk22
└───AmazonGiftCode
Make sure you installed the package using composer, and not by downloading it.
I'm guessing I have to load the package that contains the class first.
Unlike what you would normally expect when importing stuff, when using composer you only have to import the autoload.php file, and composer will take care of loading other packages as needed. By as needed what I mean is that as soon as composer sees you use the AmazonGiftCode class it will import the AmazonGiftCode package, but if one of your REST endpoints doesn't use anything from the AmazonGiftCode package it won't ever load it. This allows you to not have to worry about slowing down the entire application when you want to use a composer package for only a few endpoints. At least that's the way I understand how composer works.
Just run composer dump-autoload once and the class should known then.
You could also get verbose and use kamerk22\AmazonGiftCode\AmazonGiftCode;
But that AmazonGiftCode looks quite Laravel specific... that's why it may still fail, even if it may be found by auto-load. One needs to setup Laravel framework in the first place; just see this query (just in case if you may wonder where all these missing classes may come from).
I'm completly new to Symfony and tried the following guide: https://github.com/thecodingmachine/symfony-vuejs ... but without docker (I have a simple webspace, I can't use docker there).
Now I'm stuck right in the beginning, when calling composer install in the app root. I get the following message:
In EnvVarProcessor.php line 131:
Environment variable not found: "DATABASE_URL".
Well, that sounds easy, I have to setup an enviroment variable ... but I'm not using docker and I don't want to set up a temporarly variable in the shell. Few seconds of google helped me, that I can use .env for my problem like descriped here: https://symfony.com/doc/current/configuration.html#configuration-based-on-environment-variables
In the example project is already a .env file, so I extendet it by DATABASE_URL. But suddenly it is not taking that variable.
I'm working on a macbook with a simple apache/php setup without forther configuration.
What am I missing?
Introduction
I've never worked with a framework before (Zend, CakePHP, etc) and finally decided to sit down and learn one. I'm starting with Laravel because the code looks pretty and unlike some other frameworks I tried to install, the "Hello, World!" example worked on the first try.
The Goal
For the time being, I want my app to do something very simple:
User submits a request in the form of: GET /dist/lat,lng
The app uses the remote IP address and MaxMind to determine $latitude1 and $longitude1
This request path is parsed for $latitude2 and $longitude2
Using these two positions, we calculate the distance between them. To do this I'm using Rafael Fragoso's WorldDistance PHP class
Since I plan to re-use this function in later projects, it didn't seem right to throw all of the code into the /app directory. The two reusable parts of the application were:
A service provider that connects to MaxMind and returns a latitude and longitude
A service provider that takes two points on a globe and returns the distance
If I build facades correctly then instead of my routes.php file being a mess of closures within closures, I can simply write:
Route::get('dist/{input}', function($input){
$input = explode( "," , $input );
return Distance::getDistance( GeoIP::getLocation(), $input );
});
What I've tried
Initial Attempt
For the first service provider, I found Daniel Stainback's Laravel 5 GeoIP service provider. It didn't install as easily as it should have (I had to manually copy geoip.php to the /config directory, update /config/app.php by hand, and run composer update and php artisan optimize) however it worked: A request to GET /test returned all of my information.
For the second service provider, I started by trying to mimic the directory structure and file naming convention of the GeoIP service provider. I figured that if I had the same naming convention, the autoloader would be able to locate my class. So I created /vendor/stevendesu/worlddistance/src/Stevendesu/WorldDistance\WorldDistanceServiceProvider.php:
<?php namespace Stevendesu\WorldDistance;
use Illuminate\Support\ServiceProvider;
class WorldDistanceServiceProvider extends ServiceProvider {
protected $defer = false;
public function register()
{
// Register providers.
$this->app['distance'] = $this->app->share(function($app)
{
return new WorldDistance();
});
}
public function provides()
{
return ['distance'];
}
}
I then added this to my /config/app.php:
'Stevendesu\WorldDistance\WorldDistanceServiceProvider',
This fails with a fatal error:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
Using WorkBench
Since this utterly failed I figured that there must be some other file dependency: maybe without composer.json or without a README it gives up. I don't know. So I started to look into package creation. Several Google searches for "create package laravel 5" proved fruitless. Either:
They were using Laravel 4.2, in which case the advice was "run php artisan workbench vendor/package --resources"
Or
They were using Laravel 5, in which case the docs were completely useless
The official Laravel 5 docs give you plenty of sample code, saying things like:
All you need to do is tell Laravel where the views for a given namespace are located. For example, if your package is named "courier", you might add the following to your service provider's boot method:
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}
This makes the assumption that you have a service provider to put a boot method in
Nothing in the docs says how to create a service provider in such a way that it will actually be loaded by Laravel.
I also found several different resources all of which assume you have a repository and you just want to include it in your app, or assume you have "workbench". Nothing about creating a new package entirely from scratch.
PHP Artisan did not even have a "workbench" command, and there was no "workbench.php" file in /config, so anything I found related to workbench was worthless. I started doing some research on Workbench and found several different questions on StackOverflow.
After a long time and some experimentation, I managed to get laravel/workbench into my composer.json, composer update, composer install, manually build a workbench.php config file, and finally use the PHP Artisan Workbench command to make a new package:
php artisan workbench Stevendesu/WorldDistance --resources
This created a directory: /workbench/stevendesu/world-distance with a number of sub-directories and only one file: /workbench/stevendesu/world-distance/src/Stevendesu/WorldDistance/WorldDistanceServiceProvider.php
This service provider class looked essentially identical to the file I created before, except that it was in the /workbench directory instead of the /vendor directory. I tried reloading the page and I still got the fatal error:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
I also tried php artisan vendor:publish. I don't really know what this command does and the description wasn't helpful, so maybe it would help? It didn't.
Question
How do I create a new service provider as a package so that in future projects I can simply include this package and have all the same functionality? Or rather, what did I do wrong so that the package I created isn't working?
After two days of playing with this I managed to find the solution. I had assumed that the directory structure mapped directly to the autoloader's path that it checked (e.g. attempting to access a class Stevendesu\WorldDistance\WorldDistanceServiceProvider would look in vendor/stevendesu/world-distance/WorldDistanceServiceProvider)... This isn't the case.
Reading through the composer source code to see how it actually loads the files, it builds a "classmap" - essentially a gigantic array mapping classes to their respective files. This file is built when you run composer update or composer install - and it will only be built correctly if composer knows the details of your package. That is - if your package is included in your project's composer.json file
I created a local git repository outside of my app then added my package to my app's composer.json file then ran composer update -- suddenly everything worked perfectly.
As for the:
It didn't install as easily as it should have
the secret sauce here was first add the service provider to /config/app.php then, second run php artisan vendor:publish
Im kind of new with Travis, and I am expreimenting with it right now. I uploaded have my PHP Project on Github and when I let it test via Travis it fails and gives me this error.
PHP Fatal error: Class 'controllers\Welcome' not found in /home/travis/build/ezylot/PHPSkeleton/tests/controllers/welcomeTest.php on line 4
I use a autoloader to load the classes, and it is no problem on my local machine. I include the autoloader in bootsrap.php with the bootstrap in the PHPUnit Konfiguration-XML File.
<?php
if (!#include __DIR__ . '/../vendor/autoload.php') {
die('You must set up the project dependencies, run the following commands:
wget http://getcomposer.org/composer.phar
php composer.phar install');
}
?>
You are most likely developing on OSX which has case insensitive filesystem and tests pass. Travis uses case sensitive file system. Try renaming app/controllers/welcome.php to app/controllers/Welcome.php.
In general it is good idea to follow PSR-1 standard to avoid autoloading issues.
I had a short php open tag at the top of the class file.
<?
as opposed to
<?php
This broke it on the remote, but not on my local. Which is weird, because I would've expected it to break locally too.
Putting this out there in case someone else is in the same odd situation.
I just updated my project library folder (with an external to ZF svn) to ZF version 1.11. I'm now getting al kinds of weird errors, related to whitespaces, empty lines, etc. I searched on the internet for quite a while, but can't find a proper answer. I think this is related to some settings in my php.ini file but can't figure it out.
Example of an error:
Parse error: syntax error, unexpected $end in /library/Zend/Application.php on line 415 Call Stack: 0.0042 657160 1. {main}() /mnt/hgfs/htdocs/service/public/index.php:0
PHP version: PHP 5.3.5-0.dotdeb.1
All help would appreciated, I can't wrap my head around it!
I see you're running the project on a hgfs mount, probably inside your VM. Try to run your project off the hgfs mount as I found it to be buggy when dealing with these things.
For one, the default mount options don't keep into account that your file and directory properties (uid and gid) probably aren't the same on your guest and host system. Unfortunately, setting these right didn't fix it for me.
The solution I eventually used was to ditch the hgfs driver and mount the files using sshfs. On Debian you can just install it by running apt-get install sshfs. I then added an entry to /etc/fstab, like this:
sshfs#user#host:/path/to/host/dir /mnt/share fuse comment=sshfs,user,rw,exec,uid=1000,gid=1000,allow_other 0 0
Mounting the share can then be done by running this:
mount /mnt/share
Hope this helps!