How to let Cakephp 3 choose database connection by Apache environment variable - cakephp

I'm working with cakephp v3 and want to install the application in two different environments, one for development and one for production use. Both installations should consist of exactly the same files (and file contents), so I could use 'git' or 'svn' to easily deploy the application.
If both environments are hosted on the same machine, I need different database settings (so that the development env uses its own 'testing' DB). I thought of configuring two 'Datasources' in app.php, the 'default' one for production and a `development'.
But how can I switch between both sources?
To be more specific: Currently I define the following environment variable in my Apache config for the development environment:
SetEnv CAKEPHP_DEBUG 1
Then I changed the definition of 'debug' in the app.php file like this:
'debug' => (bool)getenv('CAKEPHP_DEBUG'),
This enables DEBUG mode only on the development machine. Now I also want to switch database configuration in the same easy way.
(I already found some solutions for cakephp v2, but all of them are pretty old and I'm not sure what's the best way to do it in cakephp v3.)

The manual says
You can define as many connections as you want in your configuration
file. You can also define additional connections at runtime using
Cake\Datasource\ConnectionManager::config().
So I guess you can check the value of debug in AppController beforeFilter and change the default database connection
AppController.php
if(Configure::read('debug') == 1)
{
ConnectionManager::config('default', [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'dev_server',
'username' => 'dev_username',
'password' => 'dev_passwd',
'database' => 'development',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
]);
}
I think you can do something similar in app.php using the ternary operator
app.php
'Datasources' => [
'default' => getenv('CAKEPHP_DEBUG')== 1 ? [ /* debug params */ ] : [ /* default params */]
...
]
But somehow it don't seem the 'clean' way to do it
I think that a cleaner way would be to set both configurations in app.php and then in appController choose what configurations to use
app.php
'Datasources' => [
'debug' => [ /* debug params */ ],
'default' => [ /* default params */]
]
Table file
public static function defaultConnectionName() {
if(Configure::read('debug') == 1)
return 'debug';
return 'default';
}

Related

Laravel - Unsupported driver

I am trying to connect to sql server but I get this error
ocal.ERROR: Unsupported driver [SqlSrv] {"exception":"[object]
(InvalidArgumentException(code: 0): Unsupported driver [SqlSrv] at
\vendor\laravel\framework\src\Illuminate\Database\Connectors\ConnectionFactory.php:283)
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('GAME_DB_DATABASE', 'forge'),
'username' => env('DB_USER', 'forge'),
'password' => env('DB_PASS', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
I'd this problem and took me a while to figure it out. It's and old question, but I'm posting how I solved anyway in a Windows DEV environment:
As stated you need to install the PHP - SQL Server drivers from Microsoft.
Problem is that Laravel (version 8.1 on Windows) do not recognise the drivers: php_sqlsrv_73_ts_x64.dll and php_pdo_sqlsrv_73_ts_x64.dll.
From \vendor\laravel\framework\src\Illuminate\Database\Connectors\ConnectionFactory.php:287
case 'sqlsrv':
return new SqlServerConnection($connection, $database, $prefix, $config);
I had to rename the driver files php_sqlsrv_73_ts_x64.dll and php_pdo_sqlsrv_73_ts_64.dll to php_sqlsrv.dll and php_pdo_sqlsrv.dll (I used the Thread Safe for x64, rename those appropriate for your installation).
In php.ini declared the extensions
extension=pdo_sqlsrv
extension=sqlsrv
And worked like a charm. If somebody knows a proper way to fix this, let me know. TY.

Josegonzalez/Upload.UploadBehavior could not be found cakephp 3.x

I have a problem configuring Josegonzalez plugin, i get an error as below
Josegonzalez/Upload.UploadBehavior could not be found.
Make sure your plugin Josegonzalez/Upload is in the C:\xampp\htdocs\sunelex\plugins\ directory and was loaded.
Error: Create the class UploadBehavior below in file: C:\xampp\htdocs\sunelex\plugins\Josegonzalez/Upload\src\Model\Behavior\UploadBehavior.php
<?php
namespace Josegonzalez\Upload\Model\Behavior;
use Cake\ORM\Behavior;
class UploadBehavior extends Behavior
{
}
I managed to get the plugin via composer into the plugins folder. I then enabled the plugin in the boostrap.php like Plugin::loadAll(); My table class behavior code looks as follows.
$this->addBehavior('Josegonzalez/Upload.Upload', [
'survey_step3_asbestos_pic' => [
'fields' => [
// if these fields or their defaults exist
// the values will be set.
'dir' => 'photo_dir', // defaults to `dir`
'size' => 'photo_size', // defaults to `size`
'type' => 'photo_type', // defaults to `type`
],
],
]);
Everything is in its place but for some reason I am getting the error above. Could you please help. Thanks.
Using cmd install below command.
composer require josegonzalez/cakephp-upload
You need to enable the plugin your config/bootstrap.php file:
<?php
Plugin::load('Josegonzalez/Upload');
If you are already using Plugin::loadAll();, then this is not necessary.

CakePHP Memcached CakePHP2.5.x

I have upgraded to CakePHP 2.5.x series and now trying to implement the new Memcached engine that replaces Memcache; however I am getting the following:
_cake_core_ cache was unable to write 'cake_dev_en-us' to Memcached cache in ...
Uncaught exception 'CacheException' with message ' is not a valid serializer engine for Memcached'
I have updated bootstrap.php and core.php with the correct values. Memcached is working correctly on my Ubuntu 14.04 server using port 11211 on localhost (127.0.0.1). Any help would be appreciated
Thanks
This is because in the Config/core.php, the following 'serialize' parameter will be set as false if the cache engine is set as "Memcached", however, MemcachedEngine requires the 'serialize' to be set among 'php','igbinary' and 'json'. You may just comment out the "serialize" line, so 'php' will be the default value.
/**
* Configure the cache used for general framework caching. Path information,
* object listings, and translation cache files are stored with this configuration.
*/
Cache::config('_cake_core_', array(
'engine' => $engine,
'prefix' => $prefix . 'cake_core_',
'path' => CACHE . 'persistent' . DS,
'serialize' => ($engine === 'File'),
'duration' => $duration
));
/**
* Configure the cache for model and datasource caches. This cache configuration
* is used to store schema descriptions, and table listings in connections.
*/
Cache::config('_cake_model_', array(
'engine' => $engine,
'prefix' => $prefix . 'cake_model_',
'path' => CACHE . 'models' . DS,
'serialize' => ($engine === 'File'),
'duration' => $duration
));

CakePHP cache permissions issues

This week I have moved a CakePHP application on the server so that it is served from C:\path\current\ where current is a symlink to C:\path\versions[date]. Previously the app was in C:\inetpub\wwwroot.
Thus each time I deploy changes, I make a new version of the app and the deploy script updates the symlink. In order to avoid having to re-create the temp dir each time, I've moved the temp dir to C:\path\app_tmp\ - the deploy script drops a symlink at app\tmp pointing to this temp dir.
The server is Windows Server 2008 R2 and the web server is IIS7. C:\path\app_tmp\ has full permissions (Everyone has Full Control).
Since making the change to the location of the app and the tmp dir, users are reporting sporadic instances of warnings appearing at the top of the page. The app is in debug=0 but these do not appear in the error log.
Examples:
Warning:
unlink(C:\path\app_tmp\cache\models\prefix_cake_model_default_app_modelname):
Permission denied in
C:\path\versions[date]\www\lib\Cake\Cache\Engine\FileEngine.php on
line 254
Warning:
SplFileInfo::openFile(C:\path\versions[date]\www\app\tmp\cache\models\prefix_cake_model_default_app_modelname):
failed to open stream: Permission denied in
C:\path\versions[date]\www\lib\Cake\Cache\Engine\FileEngine.php on
line 313
(actual paths/model names obfuscated)
Here is what I have in core.php:
$engine = 'File';
$duration = '+999 days';
if (Configure::read('debug') >= 1) {
$duration = '+10 seconds';
}
if (!isset($_SERVER['HTTP_HOST'])) {
$prefix = 'cmd_';
}
else {
$prefix = $_SERVER['HTTP_HOST'] . '_';
}
Cache::config('_cake_core_', array(
'engine' => $engine,
'prefix' => $prefix . 'cake_core_',
'path' => CACHE . 'persistent' . DS,
'serialize' => ($engine === 'File'),
'duration' => $duration,
'mask' => 0666
));
Cache::config('_cake_model_', array(
'engine' => $engine,
'prefix' => $prefix . 'cake_model_',
'path' => CACHE . 'models' . DS,
'serialize' => ($engine === 'File'),
'duration' => $duration,
'mask' => 0666
));
I have this in bootstrap.php:
Cache::config('default', array('engine' => 'File'));
Any suggestions? I have a feeling that perhaps the permissions aren't being inherited properly from the app\tmp symlink to the actual tmp dir, but on the other hand the error logs seem to write correctly and these errors are only sporadic.
One idea i had was to switch to using Wincache but then I can't find any information on how I clear the model cache when I've got a database change to deploy (currently I can just clear the model cache with a grunt task).
I haven't been able to resolve this while sticking to using the default file caching. I've switched the application to using Wincache. To clear model cache when a database change is made, I've written a short script to execute:
Cache::clear('_cake_model_');
This has to be done in the browser because CLI uses a different cache from IIS, but I've made it "gruntable" by using grunt-shell and just executing: start http://script/location/clear_cache

CakePHP + NGINX + Memcache

I am trying to use Memcache on NGINX for CakePHP (2.4.7) but when I update the core.php & bootstrap.php to do this I am then thrown the following exception:
Fatal error: Uncaught exception 'CacheException' with message 'Cache engine _cake_core_ is not properly configured
I have tried to search if any other configuration is required but can't see anything. Any help would be appreciated
Thanks,
First of all you need be sure that your Memcached configured and working properly.
Check memcached port (11211 if default settings) / process etc... for example memcached -u www-data -vv.
Then if you using memcached default configurations you should change core.php configurations like following:
Uncomment section about memcached. After it it's should looks like this:
Cache::config('default', array(
'engine' => 'Memcache', //[required]
'duration' => 1800, //[optional]
'probability' => 100, //[optional]
'prefix' => Inflector::slug(APP_DIR) . '_',
'servers' => array(
'127.0.0.1:11211'),
'persistent' => true,
'compress' => false));
Now change $engine = 'File'; to $engine = 'Memcache';
Use caching for example in controller you need write data with key => value, then access that data with key. Example:
Cache::write($key, $value);
Cache::read($key);
That's all.
Hope it's help you.

Resources