CodeIgniter 4 - Multiple Databases Problem with .env file - php

I am using CodeIgniter 4.0.3. I've installed it using composer via:
composer create-project codeigniter4/framework
Got one error after the composer project creation was finished (Script bash admin/setup.sh handling the post-update-cmd event returned with error code 127 --- running on Windows 10), but quickly resolved it by editing the composer.json and removing the bash admin/setup.sh directive
I've successfully followed up the tutorial and after that, I decided to make some changes to make it more similar to my web-app requirements, such as adding multiple databases.
Starting with the documentation (here and here), I read that I have to modify my .env file. So, here was the original
# ORIGINAL .env
database.default.hostname = localhost
database.default.database = ci4
database.default.username = root
database.default.password =
database.default.DBDriver = MySQLi
And I wanted to do something like:
# MODIFIED .env
database.primary.hostname = localhost
database.primary.database = ci4primary
database.primary.username = root
database.primary.password =
database.primary.DBDriver = MySQLi
database.secondary.hostname = localhost
database.secondary.database = ci4secondary
database.secondary.username = root
database.secondary.password =
database.secondary.DBDriver = MySQLi
Next, in my Model I have called Database to connect via:
use Config\Database;
...
$dbPrimary = Database::connect('primary');
$dbSecondary = Database::connect('secondary');
When I run the app, I get the following error:
InvalidArgumentException primary is not a valid database connection group
I don't know what else to do, I tried various edits of the .env file, tried debugging the Config class (which I think it does not load the primary nor the secondary subkeys --- nor do I have any idea on how to change the class to read them from my environment file).
Quick checklist:
env file has been moved to .env
both ci4primary and ci4secondary databases exist and have the proper tables with data
database credentials are ok
CI environment is set to development

The database connection groups in the .env file must also exist in the app/Config/Database.php file. By default only the default and tests connection groups are defined.

Related

Why can't I empty the sqlite:memory database in CodeIgniter 4?

I have a problem, I installed CodeIgniter4 and added .env file this row:
database.tests.hostname = 127.0.0.1
database.tests.database = 'sqlite::memory:'
database.tests.DBDriver = SQLite3
# database.tests.DBPrefix =
database.tests.port = 3306
Well, I started to try out the default test in CI4. The default test was successful.
And I thought that I rename the default migration file from 2022-09-26-2222-x to 2022-09-26-2223-x.
I believed that the unittest builds the database from scratch BUT I got an error like:
RuntimeException: There is a gap in the migration sequence near version number: 2022-09-26-2222-x
How it possible?
I thought that after building the database it clears the memory and so it doesn't matter about version tracking, since it's just temp memory.

Gitlab CI configuration with Laravel Docker Redis wrong host or port

I'm working on a Gitlab CI configuration in the .gitlab-ci.yml file for a Laravel project which uses redis as Cache Driver. Within this configuration file I use an image which has all the linux packages, php extension which are used on our production environment. This includes the redis extension installed by pecl so phpredis can be used within Laravel.
After spending a fair amount of time into learning the process of continuous integration and the configuration of the gitlab ci file I encountered the following error on deploy of the image:
In PhpRedisConnector.php line 126:
Redis::connect() expects parameter 2 to be int, string given
parameter should be only the port as an int but somehow turned into tcp://111.111.11.11:6379
As documented https://docs.gitlab.com/ee/ci/services/redis.html the host in your .env should be redis so I had. Dumping the config during the deploy resulted in port being some tcp://111.111.11.11:6379 connection string and host being empty. There is no way this is changed within our application or any extension we use.
I use the https://hub.docker.com/_/redis/ as a service in the .gitlab-ci.yml.
...
services:
- name: redis:4
...
Solution found here:
https://laracasts.com/discuss/channels/testing/gitlab-ci-weird-redis-host
This variable isn't documented anywhere but somehow it solves the problem.
Add the following to your .gitlab-ci.yml file:
variables:
REDIS_PORT: 6379
If anyone finds documentation about this variable and maybe more options, let me know!
This is expected behaviour from Docker.
In Gitlab CI, all services you define will be linked with your container which is running your job using Docker linking system.
As describe here, when we link containers, Docker automatically creates ENVs in format:
<_alias>_NAME
<_alias>_PORT
and some other ENVS
And those ENVs from Docker will override yours.
alias here will be the hostname of your container you defined in services. For example you define these services in your .gitlab-ci.yml:
services:
- redis:5-alpine
- name: mongo
alias: db
So Docker will create the following ENVs respectively:
REDIS_PORT="some thing looks like: tcp://172.17.0.3:6379"
REDIS_NAME="looks like: /runner-72989761-project-19846207-concurrent-0-62507216079cf651-build-3/redis"
DB_PORT=same like redis
DB_NAME=same like redis
And note that, as described here, by default the following ENVs are also auto created based on service image's name:
MONGO_PORT=...
MONGO_NAME=...
So in your code if you have any variable that has same name with the ones Docker creates, you may need to change your variable's name otherwise it'll be override by Docker. Or you can use the solution from #MmynameStackflow above, pass variables in your Gitlab CI config file to override what Docker does.

You have requested a non-existent service "phpexcel"

I know there are some questions almost identical but none of them seems to be my case.
I have a symfony 2.8.3 project that reads and imports data from an excel file into mysql database. Its all working nice on localhost but in the last 48 hours I've been trying to get it working on my server. Its a shared hosting, with no SSH access to the linux.
When I am trying to load it from the server I get this error: "You have requested a non-existent service "phpexcel"."
Looks like you want to use service from ExcelBundle. But that bundle is not loaded. Check if you have it added for production env.
$bundles = array(
// ...
new Liuggio\ExcelBundle\LiuggioExcelBundle(),
);
Don't forget to clear cache on production environment after any config (AppKernel.php also) change.
To clear cache run php app/console cache:clear. You can also add env parameter: --env=dev or --env=prod - depending on your env. If it don't help then just remove all content of app/cache/ directory (or var/cache/ in case of Symfony3 app)
Pawel answered correctly, but something is missing: after you add this line: new Liuggio\ExcelBundle\LiuggioExcelBundle(), to the AppKernel.php file, inside the $bundles array, don't forget to clear the cache: delete the file from app/cache/dev in case you're in developer mode or app/cache/prod in case on production mode.

Laravel 4.1 to Heroku: SQLSTATE[HY000] [2002] No such file or directory

I deployed my Laravel 4.1 app in Heroku by following this article http://phpartisan.tumblr.com/post/71580870739/running-laravel-4-on-heroku
The static HTML homepage loaded okay but when I am trying to log-in, I am getting the error
SQLSTATE[HY000] [2002] No such file or directory
My local setup is Laravel 4.1 & MySQL.
I don't think there was a database created when I deployed.
Do I need to do it manually? How and what will be my settings then?
thanks!
The problem could be your environment might still point to local. in cli, type heroku run php artisan env to find out.
else, you might wanto run php artisan migrate --env=production to set it to the correct production environment.
you might then encounter another issue like this:
PHP Fatal error: Call to undefined function Symfony\Component\Console\mb_convert_variables() in /var/www/mysite/vendor/symfony/console/Symfony/Component/Console/Application.php on line 1154
Trust me, tt has nothing to do with mb_string module like what this post stated.
Laravel: Call to undefined function Symfony\Component\Console\mb_convert_variables()?
The problem is at environment setting.
First, make sure you have .env.php file at same dir level with composer.json and it is exists in your heroku instance. Since you cant FTP inside, you need to push to repo. But laravel tell you this is git ignored, so you will need to temporary allow it to push to your heroku repo.
Next, you will need to edit the bootstrap\start.php
replace the $env = $app->detectEnvironment(function(){}) to:
$env = $app->detectEnvironment(function() {
return file_exists(dirname(__FILE__) . '/../.env.php')
?
'production'
:
'local';
});
Once you done all these, rerun the migrate command and it will works.
You may follow this link for reference.
Laravel environment config not loading, migration fails - SQLSTATE[HY000] [2002] No such file or directory

Doctrine error: "Failed opening required '/tmp/__CG__Source.php' "

I am trying to migrate my PHP application to an Ubuntu server, but without succes. Any help would be appreciated.
First I installed Doctrine successfully into /jorrit/myapp, following the first part of Doctrine's Getting Started manual (till "Generating the Database Schema"). Secondly I placed my PHP scripts (which use Doctrine) in folder /jorrit/myapp.
When I try to run my PHP script in the CLI, I get this error messages:
PHP Warning: require(/tmp/__CG__Source.php): failed to open stream: No such file or directory in /jorrit/myapp/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php on line 200
PHP Fatal error: require(): Failed opening required '/tmp/__CG__Source.php' (include_path='.:/usr/share/php:/usr/share/pear') in /jorrit/myapp/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php on line 200
Bootstrap.php looks like this:
<?php
// bootstrap.php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
require_once "vendor/autoload.php";
// Create a simple "default" Doctrine ORM configuration for Annotations
$isDevMode = false;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode);
// the connection configuration
$dbParams = array(
'driver' => 'pdo_mysql',
'host' => 'xx',
'user' => 'xx',
'password' => 'xx',
'dbname' => 'xx',
'profiler' => 'false'
);
// obtaining the entity manager
$entityManager = EntityManager::create($dbParams, $config);
?>
The first lines of my PHP script:
<?php
require_once "bootstrap.php";
require_once 'classes.php';
$connection = $entityManager->getConnection();
The application works fine in my development environment (Windows). The /tmp folder exists and is accessible. The database is migrated succesfully and exists. I did not change anything in the vendor folder.
Any ideas? Thanks in advance for your help.
TL;DR You'll just need to generate your proxy classes manually
vendor/bin/doctrine orm:generate-proxies
Doctrine uses Proxies to connect the to database. Proxies are generated from the the Entity classes.
In development mode, it generates a Proxies on every request because you could make changes to Entity classes.
In production mode, it does not generate Proxies every time. For performance reason, it assumes the Proxies exist and include them directly.
There are a few mode for Proxies generation:
ALWAYS - It alwayes generates Proxies, this is the default setting for development mode
NEVER - It never generates Proxies, this is the default setting for production mode
ON_DEMAND - It only generates the Proxies if the Proxy files do not exist. The drawback of this option is that it has to call file_exists() every time which could potentially cause a performance issue.
Now the command
vendor/bin/doctrine orm:generate-proxies
generates Proxy classes to /tmp. I would say this might still cause trouble because other applications
on your server might delete these files unexpectedlly. One option is you can change your /tmp directory access permission to 1777
sudo chmod 1777 /tmp
The stricky bit '1' in front of 777 means that, although everyone can read/write to the /tmp directory, but you can only operate on your own files. i.e. You can't remove files created by other users.
For further reading, please have a look at
http://docs.doctrine-project.org/en/latest/reference/advanced-configuration.html#auto-generating-proxy-classes-optional
You can also set the Proxies directory to somewhere else so no other applications can modify them. http://docs.doctrine-project.org/en/latest/reference/advanced-configuration.html#autoloading-proxies
In code after $config line you could try
$config->setAutoGenerateProxyClasses(true);
But the CLI version is much better, because it avoids on refresh regen as in code might not avoid.
To change cache dir you could try:
$cacheDir = dirname(__FILE__).'/cache';
if (!is_dir($cacheDir)) {
mkdir($cacheDir);
}
$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode, $cacheDir);
Looks like a permission problem, first should chek on permissions for the entire application folder.
Also try to hard-cleanup cache by deleting app/cache/* files, and try again.
Good luck!

Categories