How can I deploy static web app on Heroku - php

I followed instructions from an answer of a similar topic(https://stackoverflow.com/a/17531897/4388482). Well, my app is getting deployed on Heroku but it doesn't work good. I'm getting the following warning
Your project only contains an 'index.php', no 'composer.json'.
Using 'index.php' to declare app type as PHP is deprecated and may lead to unexpected behavior.
Do I need to install something maybe?
UPDATE
Project structure was initially this:
I did the following:
Installed PHP 5 and composer.
I renamed package.json to composer.json and removed package-lock.json.
Typed "composer update" command. I got "nothing to install or update" message.
Added vendor to gitignore. Pushed changes to heroku.
I got the following warnings
Your 'composer.lock' is out of date!
Composer vendor dir found in project!

The complaint that Heroku has is regarding this folder.
For the record, the contents of this folder presently are:
bootstrap
fontawesome-free
jquery-easing
jquery
What has happened here is that someone has committed dependencies to your version control, which is not good practice. It will work as is, but it is not very easy to do upgrades, especially since you cannot easily see what versions you currently do have.
There are three ways to go about this.
Decide if these are PHP dependencies, by searching Packagist. There is a Composer dependency for Bootstrap, but you would need to see if the version you are using is available (or whether you can upgrade to one that is available).
Decide if these are JavaScript dependencies, by searching NPM. I wonder if it is worth examining the contents of your package.json in case these are already covered. For what it is worth, I would generally consider these candidates for JavaScript libraries rather than PHP, but do what works for you.
Choose to leave these dependencies committed in the existing vendor folder. It will work, but it is not ideal for the reasons already stated.
In the last two cases, you could probably get away with a composer.json file thus, which you should commit to the repo:
{
"require": {
}
}
You could try a composer install after this, to see if it will generate a .lock file on an empty dependency list. If this does generate, then you should commit this also.

Related

How does the "composer" package manager work?

I am trying to install "Krumo"
It says there are two ways to install, I tried the first one (download the PHP file and include it into my project) and it worked fine.
Now I am trying the second way (using composer).
Bunch of questions emerge at the second I see it.
Where to run this command?
Is it equivalent to downloading the "class.krumo.php" file and other skin files to the current folder?
Do I still need to include the file in my PHP?
Or, maybe through running this command, krumo becomes a built-in function of PHP on my machine (so I can use it "out-of-box" on any PHP file)?
I managed to find that this install command doesn't actually work (probably outdated), and found out that I had to run composer require kktsvetkov/krumo. I did so and got this:
It seems to me it is finally installed. Under the folder there are only two files added "composer.lock" and "composer.json", the class.krumo.php file is nowhere to be found, and of course calling krumo() in a test PHP file throws the error call to undefined function krumo.
I need a big picture of how composer packages work.
First, you need to understand what composer is. It's a "dependency manager". So it manages your application dependencies, basically the libraries your application needs to work.
It does so recursively. So if your application requires NiceDependency to work, and NiceDependency in turn requires AnotherNicePackage, it installs both. It deals also with conflict resolution (when one of your dependencies requires something that's not compatible with something that another of your dependencies require).
The file where your dependencies are declared is composer.json.
So when you run composer require [some-vendor/some-package], a few things happen behind the curtain. Simplifying things a lot:
If your composer.json file doesn't exist, it will create it.
It will try to find your dependency in the central repository (packagist.org)
If found, it will download the package and store it in the vendor directory.
It will update your composer.json it to add your dependency to the require key.
In the process, it will resolve all the nested dependencies and do the same for those.
When it's done, it will also create a composer.lock file.
This "lock" file stores a frozen snapshot of all the references to all the packages that were actually installed. This is necessary because when you declare your dependencies you can define a range of versions (e.g "anything greater or equal than version 2.2; but lower than version 2.3"). Your composer.lock would store the specific version that's actuall installed (e.g. "version 2.2.4").
Later, if someone got your project files and executed composer install, the lock file would be read so they installed exactly the same files as you did.
(require adds a dependency to your project's composer.json file; install reads your composer.json and composer.lock files and sets up a project from there; there is also a update command that would read only composer.json, download the latest available packages respecting to the version restrictions in each dependency, and update `composer.lock accordingly)
Additionally, composer helps with autoloading, to make the process of actually using the installed libraries easier and faster for developers.
Autoloading is very convenient. Not only you no longer have to add a require someclass.php; statement for each class you want to use, but you also gain the advantage of not having to read these files until they are actually needed.
So not only it simplifies using these new classes, it helps making your application perform better.
For this, inside the vendor directory a file named autoload.php is created. Typically, you need to require this file as the first thing you do on your application entry point.
For example, assuming you have a structure like this:
- project root/
--- composer.json
--- composer.lock
--- vendor/
--- public/
----- index.php
Your index.php file should read:
// public/index.php
<?php
require('../vendor/autoload.php');
This would allow you to use any installed library normally. In the case of the tool you want to install:
// public/index.php
<?php
require('../vendor/autoload.php');
$a = [
'foo' => 'bar',
'baz' => [1, 2, 3],
'xxx' = false
];
krumo($a);
As a side note, that library seems to be quite old. I'd try to get something a bit newer. I'd recommend Symfony's VarDump component.
And no, it is not a particularly friendly "newbie" tool. It helps dealing with a lot of things, but it's mostly aimed to slightly more advanced users, since it helps solving issues that aren't so significant in starter/very simple projects.

PHP packages installed by Composer - should they be in source control?

I am reading/learning about Composer, the application-level package manager for PHP.
In this blog post written by lead dev Jordi Boggiano, he writes:
Composer on the other hand forces you to declare your project
dependencies in a one-stop location (composer.json at the root). You
just checkout the code, install dependencies, and they will sit in the
project directory, not disturbing anything else on the machine.
Another related feature is the composer.lock file that is generated
when you install or update dependencies. It stores the exact version
of every dependency that was used. If you commit it, anyone checking
out the project will be able to install exactly the same versions as
you did when you last updated that file, avoiding issues because of
minor incompatibilities or regressions in different versions of a
dependency.
If I understand Composer properly, when we're talking about packages downloaded/installed by Composer, we are talking about PHP code packages, ie, programming code written in PHP, and not system-level packages, eg, extensions to the PHP runtime installed on the server. So once these PHP code packages have been downloaded and added to a PHP project, I would have thought those packages become part of the PHP application source code, eg to be checked in to whichever version control system is being used for the project. If another developer comes along and checks out the code, why would they need to then "install the packages", as is stated in the blog post? Wouldn't they get a copy of all code packages when they check out the code from source control? This line in the blog post is confusing me, and making me think I don't understand Composer.
Any clarity on this would be greatly appreciated. Thanks.
The dependencies themselves should not be commited to source control. The composer.json and composer.lock files, on the other hand, should. There's various reasons for this, amongst them:
Every time you update the dependency you would have to commit the changes. That kind of tightly couples your code to the dependency, when it should be exactly the other way around.
The packages themselves are already in their own repository with their own history. Why repeat that in your project's history?
Those repositories can be huge, just muddling the waters around your project. Why carry around all that weight?
Instead, having each developer just run composer install (very important: not composer update) whenever they check out the project is much more efficient. Composer will install the dependencies from composer.lock, making sure everyone running the same commit is on the exact same page. The same goes for deploying.
You can read more about this here.
On the other hand, there might be situations where you have to commit your packages to get around a problem, like for example when you know you won't be able to run composer install on your production server (shared hosting)
Normally packages installed via composer don't get checked in to source control, only the code you write and the composer.json and composer.lock files.
This way the repository for your project does not get bloated with code you did not write and possibly don't really care that much about.
Yes its normal after cloning down your repository a developer will need to run the "composer install" command. The composer.lock file will ensure they get the same modules and versions of them you used when creating your project.
Not including the composer modules in your source control also allow you to easily update to the modules to get bug fixes and new features in new versions of them.

Is there a PHP/Composer tool which works like npm version?

Is there an automated way of updating the version number in composer.json and adding the necessary tags before publishing, like the way npm version does?
I mean, if you had a composer.json with the line "version": "2.1.3", and executed:
composer version minor
It would do the following:
Updating the version number in composer.json to 2.2.0
Triggering composer update to update composer.lock
Making a new git commit
Making a new git tag v2.2.0
I know that the composer version command doesn't exist, but is there an equivalent tool?
npm version does stuff that you very likely do not need for Composer:
The version number is not recorded in composer.json if there are other means available - and because you are referring to Git later on, they are available.
Updating dependencies in the lock file is unnecessary. The lock file will be ignored when the project you are dealing with is included somewhere else.
Because nothing has changed in the project, a git commit wouldn't do anything.
All this leaves you with creating a new tag in the Git repository. Putting this into Composer would mean you'd exchange one command with another, without any big benefit besides you won't have to lookup the current version number you are dealing with if you use some of the relative version parameters.
All in all I'd say that simply tagging your new version is enough for Composer. You'd probably need to have some infrastructure in place and configured to make the world aware of the new version:
If your package is open source and on packagist.org, you should have a post-commit hook to notify them as soon as a new version is available. This is a standard option on Github, I don't know about other source code hosts.
Otherwise if you have to feed closed source code, you'd probably start a new update cycle of whatever system is used to create an alternative package information source (be it Satis, locally hosted Packagist, Toran Proxy or Private Packagist)
This however depends on how you set up things.
If for some reason and despite all voices against it you still want to use a tool like the OP asked for, https://www.npmjs.com/package/composer-version works quite well.

Composer autoloader, github and deployment

I am sorry if this has been asked before but after searching for a while I couldn't really find answers to my dilemma.
I am part of team that is working on a PHP project and we use github for our version control. We would like to implement a PSR-4 autoloader and every single guide uses Composer so we would as well. Now, while searching I learned that the vendor folder should not be included into github, but only the composer.json and that every developer needs to install composer onto their own computer.
Does that require the autoloader to be created again on every developers computer.
And finally, when the project is done, we would like to upload it onto our website, but the only way we can do that is through FTP.
Which files should be uploaded to the live website and what would happen to th autoloader?
You need to commit the composer.lock file as well. That's super-important - it means that whenever someone else checks out the code they get the same set of dependencies (including their exact versions) installed to their /vendor directory.
That's why you don't need the /vendor directory to be committed - the lock file takes care of ensuring the dependencies are fixed.
The composer.json defines numerous potential versions of your dependencies that meet your requirements. Running composer update essentially checks to see if a more recent version is available that meets those requirements. That's the difference between install and update - install goes off the lock file and knows exactly what to look for - update goes off the json file and could return different results at different points in time.
In your composer.json you can define the autoloader by telling it where your root namespace lives.
"autoload": {
"psr-4": {
"RootNamespace\\": "library/src"
}
},
When your colleagues have run composer install it will create the autoloader for them in a consistent path.
You have options for deployment:
You can either upload the composer.lock file and run a composer install on production, or do it ahead of time and upload your vendor directory as part of the build.
I do the latter as I would prefer if there was an issue at this point to know about it before any files are changed on the production server. The alternative could leave a botched upgrade on production with missing dependencies. Safer to install those dependencies first and transfer everything in one go.
As an aside, I also like to install a fresh release to a separate folder on production named after the git commit and then symlink it as part of the deployment step. This ensures you don't have a half-updated application whilst you wait for the rest of the files to be uploaded. This approach would also eliminate the issue mentioned before, meaning you could do your composer install from production.

How to develop PHP packages in a team using composer?

Introduction
This is quite a lengthy question, the question I asked in the title is probably ambiguous and I may change this to something more suitable.
A similar question has already been asked and answered here although I do not think this entirely answers the question.
Synopsis
I am working with a team of developers on a project. We are using a framework (for argument sake - the framework is irrelevant) except one of the requirements is that we use composer.
These packages are essentially de-coupled from the application and each other, however one package may depend on another package.
These packages have their own git repository, and during development of the application have branch aliases set to dev-master.
Problem #1
In order for the application to work with my packages I need to register them with composer.json, which is fine until I have to commit the existing work of my package development to their repository before I can run composer update.
Problem #2
I have committed the initial package architecture and the composer.json. I run composer update which completes and my package is available to the application. Yet, I continue to develop this package at the same time another developer has already committed a different change to this package - i.e. a bug fix.
I need to update another package in order for my work to continue, yet I can't because doing so would throw a warning similar to:
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Removing hu/admin (dev-master)
The package has modified files:
M composer.json
M src/...
Discard changes [y,n,v,?]?
If I respond with y my changes are blown away and lost forever. If I choose n composer is aborted and my project is broken due to a package not being updated parallel to my changes.
Problem #3
Another problem with this way of developing is that if I am working on my package outside of vendor and I commit my changes I can run composer update but my application is broken due to a fatal error. I fix the missing ; or other small syntax error. I commit this change and run composer update - yet I don't want my git history full of little typo fixes and parse error fixes just because I can't work on my package within the application parallel to other development/developers on the application and other packages or this package.
Problem #4
I discovered a package on GuitHub called franzliedke/studio which seems to part-solve my problem. Once a package has been published due to being complete/functional, this then cannot remain inside the vendor/bin directory alas causing the initial problems to rise once more.
Conclusion
I am wondering the best way to work around this or any best practices in order to work on packages with teams of developers without having to commit everything every time before I run composer update.
laravel did have a workbench feature which was pretty cool. But was removed from version 5.0 and so was that bad practice?
That's what we do in huge projects consisting of several little composer components which are developed at the same time:
Develop your application 'in one piece' like described in the other answer your mentioned by just keeping all components separate inside their own namespaces and directory structure.
/Application
-composer.json (Application json)
-/src
--/Component1
----composer.json (Component json)
--/Component2
----composer.json (Component json)
--/ApplicationFeature
----Class1.php
----Class2.php
The whole application is developed in a single git repository which would eliminate most of your aforementioned problems. Then occasionally split the application repo into single component repositories using git subtree. I wrote a little php cli script which splits the project into smaller components and pushes them to the according component repositories. There are a lot of advantages compared to git submodules. The whole commit history of a component is kept and pushed to the component repository. More information on subtrees here
In case you are interested please let me know, I am happy to share the script which splits/tags and finally pushes the single components by just defining a directory <-> componentName mapping as a json.

Categories