PHPUnit + Composer folder structure git vs server deploy - php

I try to add PHPUnit tests to my existing php project.
Applying the recomended folder structure for phpunit (https://phpunit.readthedocs.io/en/9.5/organizing-tests.html), I encounter the following problem deploying it to the server.
Current setup php+composer without phpunit
Checked out from git Git + composer install:
- my.php
- composer.json
- composer.lock
- vendor/
I copy php files and vendor folder to a path on the server
Server:
- path/my.php
- path/vendor/
So the URL is https://server/path/my.php
In my.php I include the composer dependencies like this
require_once 'vendor/autoload.php';
New setup with phpunit included
With recomended folder structure for phpunit (https://phpunit.readthedocs.io/en/9.5/organizing-tests.html)
Checked out from git Git + composer install:
- src/my.php
- tests/mytest.php
- composer.json
- composer.lock
- vendor/
In my.php I now include the composer dependencies like this
require_once '../vendor/autoload.php';
Problems with new setup
If I copy src+vendor/ to path/ the server the URL would be different (https://server/path/src/my.php).
If I copy src/*.php and vendor/ to path/ I would have to change the require_once upon deployment for it to work.
Desired result
tests seperated from src
accessible via the same URL
not having to change php file content uppon deployment (CD)
The closest solution I came up with
Is to not implement recomended directory structure, leave my old structure, and just create a tests/ directory.
My question
Is there a best practice solution keeping the src+tests directory structure while keeping the same URL and not having to modify src files upon deployment?

Related

Symfony 5 deployment issues (showing empty page)

This is my first deployment in Symfony 5 and I've been struggling a couple days with deployment because my website is showing a blank page.
I'm using Infinity Free Web Hosting with:
PHP Version 7.3.6
Apache
My website doesn't have a db.
So before I start to upload files with FileZilla, I run this commands:
SET APP_ENV=prod
composer install --no-dev --optimize-autoloader
composer dump-autoload --optimize --no-dev --classmap-authoritative
My folder structure goes like this
htdocs
\css
\downloads
\images
\scripts
.env.local
.htaccess
index.php
\symfony
\bin
\config
\src
\templates
\translations
\vendor
\var
composer.json
And modified index.php with new path:
require dirname(__DIR__).'symfony/vendor/autoload.php';
The issue is that the page is showing completely blank (not even an error). What is my mistake?
I've been following instructions with this tutorial, create a "symfony" folder with bin, config, src, templates and vendor, and I copied my "public" folder content to /htdocs folder.
Hosting provider doesn't allow me to upload content at the server root folder.
Thanks in advance.
You missing a / on your require :
require dirname(__DIR__).'/symfony/vendor/autoload.php';
Maybe use dev environment for debugging your application.
You have a .env.local : are you sure is necessary and correctly read ? (symfony/dotenv is a devDependency by default)
And I think is not a good practice to have your symfony folder and index.php on same directory because it can expose your source code and sensitive data. Maybe use htaccess to expose only symfony public directory.

How to install composer dependencies when the root folder of the Google App Engine project is outside the composer.json directory?

I'm using Google App engine to deploy a PHP project.
I'm using the following file structure.
public/project_files_here_composer.json_here_too
private/some_private_files
app.yaml
In app.yaml I set the public folder to be the web root directory that contains the index.php .
When I deploy this with google app deploy , my composer dependencies are not installed.
How to tell Google App Engine to install my dependencies inside the the public/ folder (using the composer.json in the public folder) ?
I've been searching on the documentation for the gcloud app deploy operation and the app.yaml file and I didn't manage to find any reference to what you intend to do. Trying to reproduce your scenario, what I did was to create a soft link in the app's root directory that pointed to the composer file in another folder, but it didn't work.
What did work was creating a hard link in the app's root folder with the following command:
ln public/composer.json composer.json
Regardless, when I made the gcloud app deploy command, it said that it was uploading 0 files (which is kinda true), but when I looked on the source from the Console, the file was there and the dependencies were installed, so it works.
If you don't want to create a hard link, you should just create a script that copies the file, deploys and removes it. Something in the lines of:
#!/bin/bash
cp public/composer.json .
gcloud app deploy
rm composer.json
If none of these works for you, you should just move the composer.json to the app's root directory.

Deploying only the generated code, without the composer.json file, and with "vendor" inside the "src" directory

I have a project with all the composer.json, phpunit.xml, etc in the project's root directory.
All the .php sources are in src/
I have configured composer.json as follows:
{
"name" : "myproj",
"config" : {
"vendor-dir" : "src/vendor"
},
"autoload" : {
"psr-4" : {
"myclasses\\" : "src/classes"
}
}
}
This works beautifully on my dev machine.
The issue is that I only want to deploy the contents of the src directory so that I do not get all the project metadata on the deployment server.
Unfortunately the autoloader looks for the classes in /var/www/test/vendor/composer/../../../src/classes/ instead of e.g. /var/www/test/vendor/composer/../../classes/
PHP Warning: include(): Failed opening '/var/www/test/vendor/composer/../../../src/classes/myclasses/core/messages/MessageList.php' for inclusion (include_path='.:/usr/share/php') in /var/www/test/vendor/composer/ClassLoader.php on line 444
Is there a clever configuration I can make? Or am I forced to move composer.json (which I see as meta-data not needed for production) into /src?
The composer.json file it's never used at runtime. There is no use for it anyway, it's only used by the composer command. If you do not run composer in your production machine, you do not need to ever upload it.
Your project it's not failing because "you are not deploying composer.json" with the code, but because you are dumping the autoloader having certain structure, which you actually mention in your composer.json configuration, and then trying to run the server with a different directory structure.
When you run composer install and composer dumpautoloader your project looks like this:
composer.json
src/ <--- this is where autoloader looks for your files.
--- yourCode/
--- moreCode/
--- vendor/
------ autoloader.php
But then in your server you on your server you have
yourCode/
moreCode/
vendor/
--- autoload.php <--- this can't find the 'src' directory
The solution is not to upload the contents of your src directory, but the src directory itself.
Any other script that needs to use the autoloader and the rest of the code should just include /var/www/test/src/vendor/autoload.php and everything would work as it should.
If you do not want to have a src directory inside test, then you shouldn't have it during the autoloader generation. Do not make your development and staging environments different from your production environment.
Your only alternative would be to do in your build machine:
run composer install
move composer.json to src
change composer.json so the paths declared on the autoload key do not mention src
run composer dumpautoload
delete composer.json
upload src contents.
It's not guaranteed to work and it's a brittle solution, but the problem is that you are trying to use the tool in a way that runs counter to the design of the tool.

CodeIgniter Composer "package.json" locations shluld be in application or root folder?

I working with code igniter v3.x and I would like to add some composer packages.
looking at application/config/config.php file, it says that will load packages inside application folder
| package auto-loader script in application/vendor/autoload.php.
However in the codeigniter package it already has a package.json that installs packages on root folder.
I suspect that the package.json on the root must hold only information about CodeIgniter it self. But I'm not sure.
So I have three options:
Create a new package.json inside the application folder and install packages inside application.
Modify the package.json on the root folder by adding new package and change autoload.php location
What is expected from a CodeIgniter Application?
Well, if you take a look at the Codeigniter Documentation you can see there is a Configuration setting called composer_autoload. This information can be found here.
If you set this true, Codeigniter tries to load Composer's autoload.php in the APPLICATION.'vendor' folder. If you take a closer look at the Codeigniter.php file, you'll see that you can define a directory for this setting too.
So in your case you don't have to change the package.json in the root folder because you need one in the application folder, in case you set composer_autoload to true, which i would recommend.
By the way if you try to install a package via composer in your application directory, composer asks you if you want to use the one it found on the root folder - just decline that and press n.
As you can see in the picture below (i just tried to install the mpdf package).

Installing laravel on existing project

I'm developing a laravel application and my computer die.
Now I want to get my project from the repository (Bitbucket + Git) but thanks to the git ignore file, the vendor folder is missing. I can't do a composer install on my project because is not allowed (the directory should be empty). The structure of my project is the same as the laravel installation except that I renamed the public folder.
I found this thread but did not solve my problem.
Integrating existing project by laravel framework?
I wanna know the best practice or way to do this and i don't think that copy and paste the folder of my project to a fresh install of larevel should be the way.
Thanks.
Go to your www folder
cd /var/www
Git clone your application (not that here the directory must not exist):
git clone https://github.com/antonioribeiro/application
CD into the folder
cd application
Execute composer update (if you are in a development environment)
composer update
Or execute composer install (if you are in a production environment)
composer install
Note that for composer install or composer update, the folder may actually have files and even a vendor folder created, there is not such obstacle.

Categories