Reputation: 1670
I want to provide a script that can be installed with PHP's package manager composer
and that must be configurable.
With composer, we can easily define vendor binaries.
However, I don't see any possibility to configure them.
One could include a configuration file from within the package. However, name and location of the vendor directory are configurable, so this will not be very reliable.
For comparison: With Python's package manager pip
, we can use environment variables for the configuration. We can set the environment variables while activating the virtual environment, e.g. by using tools like the virtualenvwrapper
.
There must be at least experiments with similar approaches in the PHP community.
Addendum: The story behind
I have scripts that synchronize the databases and user generated files for test versions of websites.
For Django sites, I'm always using the same scripts, they rely on environment variables that I define with the virtualenvwrapper.
For Drupal sites, one can achieve a lot with drush.
But for Wordpress, I cannot find a simple and clean tool. It should
To be honest, I'm missing the virtualenvwrapper in PHP. The virtualenvwrapper is a linux script that basically does two things:
Upvotes: 13
Views: 2957
Reputation: 1711
I think, what are you looking for is probably something like a library https://packagist.org/packages/hiqdev/composer-config-plugin
It is a quite popular library and managed also by a creator/contributor of the Yii/2 framework Samdark https://packagist.org/users/samdark/ or the creator of the asset-packagist hiqdev https://packagist.org/users/hiqdev/
This Composer plugin provides assembling of configurations distributed with composer packages. It allows putting configuration needed to use a package right inside of the package thus implementing a plugin system. The package becomes a plugin holding both the code and its configuration.
Usage:
"extra": {
"config-plugin-output-dir": "path/relative-to-composer-json",
"config-plugin": {
"params": [
"config/params.php",
"?config/params-local.php"
],
"common": "config/common.php",
"web": [
"$common",
"config/web.php"
],
"other": "config/other.php"
}
},
Upvotes: 1
Reputation: 6842
As other users, I'm unsure what your end goal is here but what you have seemed to have outlined appears to break the point of using composer the whole point of the composer is that the code works with any application & required dependencies are obtained on install.
For What your trying to do of creating a setup for "configuration setting" are normally implemented by setting up a configuration interface that the using App has to create and provide for your class / created objects to initialize.
For example, your composer lib requires a login system now it could well be the app it's being used /installed in to already has a login system. No developer ever want two different login tables for a single app in their Database so you should create an interface that developers app can implement and provide the configuration that is needed
Code Example:
Example class to do something (your library entry class)
<?php
namespace my_namespace;
class DoSomething{
private $config;
public function __construct(\my_namespace\interface\Config $config)
{
$this->config = $config;
}
function doLogin()
{
// get $username and $password
$state = $this->config->CheckUserLogin($username, $password);
if(!is_bool($state)){ throw new Exception("State of CheckUserLogin from class '".get_class($this->config)."' is incorrect expected boolean but '".gettype($state)."' was provided"); }
}
}
Example Config Interface: (your composer's library config interface)
<?php
namespace my_namespace\interface;
interface Config{
public function CheckUserLogin($username, $password);
//....
}
This means i could install your Library via composer and setup like so.
Example my app Config for your library: (the class the using app has to build inheriting your interface)
<?php
namespace myapp;
class DoSomethingConfig implementes \my_namespace\interface\Config{
public function CheckUserLogin($username, $password)
{
// do my login system ($loginState)
return $loginState;
}
}
Example my initializing of your library: (the code any app would have to use)
<?php
namespace myapp;
class ConnectToSomething{
private $lib;
public function __construct(){
$config = new \myapp\DoSomethingConfig();
$this->lib = new \my_namespace\DoSomething($config);
}
}
This way you give developer free reign to work with your code base. while they should never be wanting to edit your classes because you have done something that would cause duplicate information.
This is a simple example that highlights the point I'm trying to make don't try to run a config script to get the users to setup stuff for your library make them set up the stuff that needed in a way where they can then manage that connection point between your code and there's, this also provides security as they know your not accessing information you should not be and send it to your servers.
As they provide your code with the access it requires to work and nothing else.
Upvotes: 1
Reputation: 2055
With a composer you can do something like that (PATH is your environment variable):
{
"name": "test/test",
"authors": [
{
"name": "Test",
"email": "[email protected]"
}
],
"require": {
},
"scripts": {
"post-install-cmd": [
"@echoPath"
],
"post-update-cmd": [
"@echoPath"
],
"echoPath": "echo $PATH"
}
}
Not sure if this is what you want.
Upvotes: 2
Reputation: 547
You can add a post-package-install script. With that you can use something like symfony/console to allow the installer to do some sort of configuration.
Upvotes: 3
Reputation: 217
I'm not sure what you're trying to achieve, but there are plenty of options if you want to use env vars in Php.
https://github.com/symfony/dotenv is one of them and well maintained.
<?php
use Symfony\Component\Dotenv\Dotenv;
$dotenv = new Dotenv();
$dotenv->load(__DIR__.'/path/to/.env');
Then you can use those env var the way you want for configuration purposes. E.g. for DB config:
$someSettings = [
// Db config
DB_CONNECTION => [
'host' => getenv('DB_HOST'),
'username' => getenv('DB_USERNAME'),
'password' => getenv('DB_PASSWORD'),
'database' => getenv('DB_DATABASE')
]
];
Upvotes: 3