CI3 – redis code example

check the previous ci3 and redis setup

cat application/controllers/Tredis.php
<?php
defined('BASEPATH') or exit('No direct script access allowed');
require_once APPPATH . 'libraries/codeigniter-predis/src/Redis.php';
require_once APPPATH . 'libraries/codeigniter-predis/src/RedisServer.php';
require_once APPPATH . 'libraries/codeigniter-predis/src/RedisServerCollection.php';


class Tredis extends CI_Controller
{
	function queue()
	{

		$this->redis = new \CI_Predis\Redis(['serverName' => 'redis']);

		$data = [];

		foreach ($_POST as $var => $_) $data[$var] = $this->input->post($var);

		echo $this->redis->rpush("costumer_register", json_encode($data));

		echo "Customer details accepted successfully.\n";
	}

	function worker()
	{
		$this->redis = new \CI_Predis\Redis(['serverName' => 'redis']);

		$data = $this->redis->lpop('costumer_register');

		$data  = json_decode($data, true);

		if (!empty($data)) {

			$this->load->model('foo/foo_m');

			$this->foo_m->__insert('testtest', $data);

			echo $data['first_name'] . " " . $data['last_name'] . "'s details saved to database.";
		} else {
			echo "No data in customers_register \n";
		}
	}
}

we need to create testtest table

CREATE TABLE `testtest` (
  `id` int(11) NOT NULL,
  `first_name` varchar(128) DEFAULT NULL,
  `last_name` varchar(128) DEFAULT NULL,
  `email_address` varchar(128) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

now let test with curl fill data

$ curl --insecure --data "first_name=JOHN&last_name=DOE&email_address=john_doe@example.com" https://localhost/tredis/queue
$ curl --insecure --data "first_name=MARY&last_name=SMITH&email_address=mary_smith@example.com" https://localhost/tredis/queue
$ curl --insecure --data "first_name=JANE&last_name=COTTON&email_address=mary_smith@example.com" https://localhost/tredis/queue

and test worker

$ curl --insecure https://localhost/tredis/worker

source https://www.vultr.com/docs/implement-redis-queue-and-worker-with-php-on-ubuntu-20-04/

redis docker codeigniter 3

kenapa saya membutuhkan cache ? apakah kecapatan ? IO ? atau biar keren kayak yg lain ? jawabannya karena saya tidak suka system yg mubajir.

contoh system mubajir adalah, kita butuh 1 value dari rows database, untuk 1000 jobs, lalu kita query 1000 kali untuk mendapat 1 value itu. klo itu database bisa ngomong pasti dia protes "ini udah 1000 kali lo tanya hal yang sama, 1 kali lagi lo tanya, gw ngambek".

contoh diatas bisa diatasi menyimpan value itu ke sebuah variable, sehingga hanya 1 kali query ke db (IO) dan 1000 kali akses value itu ke RAM. karena variable disimpan ke dalam RAM, dan kecepatan pengaksesan value ke ram lebih cepat dari pada ke DB (IO) atau perangkat keras penyimpanan (HARDISK).

tapi kan hardisk server saya sudah SSD, kan cepet juga tuh kalo akses. iya, tapi SSD punya keterbatasan bacatulis dan umur. so enggak bijak lah kita bergantung cuma ke SSD tapi kodingan tidak di maximalkan.

kelebihan cache adalah untuk memproses jobs. jobs ini akan di execute oleh script yg diperiodekan oleh cronjob.

jobs nya cukup banyak bisa sampai di atas 5K jobs. bayangkan jika 5K jobs ini melakukan query ke database, untuk sebuah rows yg sama, mencari value yg sama sebagai parameter, karena setiap jobs akan membuat ‘session’ sendiri sehingga jika kita buat cros variable jauh lebih rumit maintenance systemnya.sungguh tidak indah, dan riskan kesalahan.

yang paling baik dan pasti kita butuh kedepan dalam pengembangan fitur, adalah menggunakan REDIS sebagai cache.

pada project ini saya menggunakan docker (docker-compose) sebagai LAMP, sehingga menambah 1 server REDIS harus nya bukan masalah besar. dan script yg digunakan adalah codeigniter 3. kenapa CI3, karena project yg mau di implement cache ini base script nya CI3 dengan HMVC.

berikut step2 nya 0. to project folder

$ cd ~/workspace/ci3
  1. install redis pada docker-compose
$ cat docker-compose.yml

this is the content

version: "3"
services:
  php-apache:
   ...

  mariadb:
    ...

  phpmyadmin:
    ...

  redis:
    build:
      context: ./sys/redis
    networks:
      - gw_network

networks:
  gw_network:
    external: true

ini sys/redis folder punya 2 file Dockerfile and redis.conf

$ cat sys/redis/Dockerfile

FROM redis:3.2-alpine

COPY ./redis.conf /usr/local/etc/redis/redis.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]

EXPOSE 6379

and for redis.conf you can check this [https://github.com/DragonBe/docker-php-redis-example/blob/master/.docker/cache/conf/redis.conf]

now exec docker to pull and up redis server

docker-compose down
docker-compose build redis
docker-compose up -d
  1. add predis to codeigniter

my project path is ~/workspace/ci3 and ci3 code in ~/workspace/ci3/web install composer and install predis. to install composer we need php run on system, my laptop doest, so we need to go inside php-apache docker, but before that, we need to setup composer.json

$ cd ~/workspace/ci3/web
$ cat composer.json

{
    "require": {
        "predis/predis": "1.1.*@dev"
    },
    "autoload": {
        "psr-4": {"CI_Predis\\": "src/"}
    }
}

setup composer

$ cd ~/workspace/ci3
$ docker-compose up -d
$ docker-compose exec php-apache bash
root@a6d4050ee379:/var/www/html#
# echo "install composer"
# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
# php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
# php composer-setup.php
# php -r "unlink('composer-setup.php');"

install predis library with composer

# php composer.phar install
# exit

you can check in vendor folder

  1. add codeigniter-predi library

i am using code from this repo [https://github.com/Maykonn/codeigniter-predis] download only what we need

$ cd ~/workspace/ci3/web
$ mkdir -p application/libraries/codeigniter-predis &amp;&amp; cd application/libraries/codeigniter-predis/src
$ wget https://raw.githubusercontent.com/Maykonn/codeigniter-predis/master/src/Redis.php .
$ wget https://raw.githubusercontent.com/Maykonn/codeigniter-predis/master/src/RedisServer.php .
$ wget https://raw.githubusercontent.com/Maykonn/codeigniter-predis/master/src/RedisServerCollection.php .
$ cd application/config
$ wget https://raw.githubusercontent.com/Maykonn/codeigniter-predis/master/src/config/codeigniter-predis.php .
$ cd application/controllers/
$ wget https://raw.githubusercontent.com/Maykonn/codeigniter-predis/master/example/application/controllers/Welcome.php .

we need some change in config and controller. change config to

$ cat application/config/codeigniter-predis.php
 'localhost',
            'servers' => [
                'localhost' => [
                    'scheme' => 'tcp',
                    'host' => 'redis',
                    'port' => 6379,
                    'password' => null,
                    'database' => 0,
                ],
                // another instance
                'redis' => [
                    'scheme' => 'tcp',
                    'host' => 'redis',
                    'port' => 6379,
                    'password' => null,
                    'database' => 0,
                ],
            ],
        ];
        break;
    case 'homologation':
        break;
    case 'production':
        break;
    default:
        throw new Exception('The application environment is not set correctly.');
}

now change the Welcome.php

$ cat application/controllers/Welcome.php

<?php
defined("BASEPATH") or exit("No direct script access allowed");

class Welcome extends CI_Controller
{
    public function index()
    {
        require_once APPPATH . "libraries/codeigniter-predis/src/Redis.php";
        require_once APPPATH . "libraries/codeigniter-predis/src/RedisServer.php";
        require_once APPPATH . "libraries/codeigniter-predis/src/RedisServerCollection.php";

        echo "<pre>";

        echo 'See cms/config/codeigniter-predis.php file <br><br>';
        $this->load->config('codeigniter-predis.php');
        // Using the default_server configuration
        $this->redis = new \CI_Predis\Redis();
        echo 'PING server setted to default_server config param: ';
        echo $this->redis->ping() . '<br><br>';
        echo 'PING server setted to default_server config param, another way: ';
        echo $this->redis->getServerConnected()->ping() . '<br><br>';


        // Specifying hosts
        $this-&gt;redis = new \CI_Predis\Redis(['serverName' =&gt; 'redis']);

        // Ping the redis server
        echo 'PING redis server: ';
        echo $this->redis->ping() . '<br><br>';
        echo 'PING redis server again, another way: ';
        echo $this->redis->getServerConnected()->ping() . '<br><br>';


        $this->redis->getServersCollection()->getServer('another_instance_example')->ping() . '<br><br>';


        // Calling a command in a not connected server
        // echo 'PING a not connected server: <br>';
        // $this->redis->getServersCollection()->getServer('not_connected_server')->ping() . '<br>';
    }
}

ci3 – guzzle REST client

using guzzle library as rest client, collaboration with ci3.

install using composer

cd ~/workspace/myci3
composer install guzzlehttp/guzzle

open config.php

code application/config/config.php

change value and save

$config['composer_autoload'] = 'vendor/autoload.php';

create new controller

code application/controllers/Out.php

fill with code

<?php
defined('BASEPATH') or exit('No direct script access allowed');
class Out extends CI_Controller
{

  function __construct()
  {
	parent::__construct();
  }

  function index()
  {
   // echo "Hello from Out conttroller";

   $client = new GuzzleHttp\Client();
   $res = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle');
	// echo $res->getStatusCode();
	// "200"
	// echo $res->getHeader('content-type')[0];
	// 'application/json; charset=utf8'
   $a = $res->getBody();
	
   $data = json_decode($a, true);
	// var_dump($data);
   echo "<img src='" . $data['owner']['avatar_url'] . "'>";
   }
}

Codeigniter 3 – PhpWord library

PhpWord as part from PhpOffice library, using this lib to output variable from php to docx file. in this code i will using docx file as template.

download or clone PhpWord from https://github.com/PHPOffice/PHPWord.git

extract and copy src/PhpWord to our application/third_party folder

$ cd src 
$ cp -R PhpWord ~/workspace/my_ci_3/application/third_party/

lets create controller

cd ~/workspace/my_ci_3/application/controllers
code Word.php

and fill the code

<?php
defined('BASEPATH') or exit('No direct script access allowed');
include_once(APPPATH . "third_party/PhpWord/TemplateProcessor.php");
include_once(APPPATH . "third_party/PhpWord/Settings.php");
include_once(APPPATH . "third_party/PhpWord/Shared/ZipArchive.php");
include_once(APPPATH . "third_party/PhpWord/Shared/Text.php");
class Word extends CI_Controller
{	
        function __construct()
	{
		parent::__construct();
                $this->load->model('ib2_model', 'ib2_m');
        }

	function index()
	{
                // grab some value from database
		$_  = $this->ib2_m->__select('tbl_transaksi', '*', [], false);

		$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor(FCPATH . '/upload/template_nya.docx');

		$templateProcessor->setValues([
			'terbilang'     => $_->terbilang,
			'val_jasa' 	=> $_->val_jasa,
			'val_spm'	=> $_->val_spm,
			'desc_jasa'	=> $_->desc_jasa,
			'desc_spm'	=> $_->desc_spm,
			'sub_total'	=> $_->sub_total,
			'ppn'		=> $_->ppn,
			'pph_23'	=> $_->pph_23,
			'total'		=> $_->total
		]);

		header("Content-Disposition: attachment; filename=template.docx");

		$templateProcessor->saveAs('php://output');
	}
}

test with url http://localhost/word/

codeigniter – oracle connection config

in codeigniter we can connect to oracle database with this config


$db['oracle'] = array(
'hostname' => '192.168.100.6:1521/EE',
'username' => 'nama_user',
'password' => 'pass_user',
'database' => '',
'dbdriver' => 'oci8',
'dbprefix' => '',
'pconnect' => TRUE,
'db_debug' => '',
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci'
);

but if had problem, mybe you must write complete connection string, with SID and SERVICE_NAME, like this

$db['oracle'] = array(
'hostname' => '(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.100.6)(PORT = 1521))  (CONNECT_DATA = (SERVICE_NAME = EE.oracle.enterprise) (SID = EE)))',
'username' => 'user_name',
'password' => 'user_pass',
'database' => '',
'dbdriver' => 'oci8',
'dbprefix' => '',
'pconnect' => TRUE,
'db_debug' => '',
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci'
);

 

centos – codeigniter remove index.php

environtment

  1. centos 6
  2. php5.3
  3. codeigniter 1
  4. apache 2
  5. path /var/www/html/project/

create file .htaccess

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
    RewriteCond %{REQUEST_URI} !/system/.* [NC]
    RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>

edit file system/application/config/config.php

$config['index_page'] = 'index.php'; 
to
$config['index_page'] = ''; 

$config['uri_protocol'] ='AUTO';
to
$config['uri_protocol'] ='REQUEST_URI';

config /etc/httpd/conf/httpd.conf

<Directory "/var/www/html/project">
    Order allow,deny
    Allow from all
    Allowoverride all
</Directory>

<IfModule mod_rewrite.c>
    RewriteEngine on
</IfModule>

restart apache

sudo service httpd restart

codeigniter – failed upload csv

upload csv file but there had error “The filetype you are attempting to upload is not allowed.

what i miss ?

  • the extension is .csv
  • the folder upload is writeable
  • the config/mime.php csv have text/csv
  • the upload config “allowed_path” have “csv”

i generate csv using libre office, problem ?

https://stackoverflow.com/questions/29167444/codeigniter-error-the-filetype-you-are-attempting-to-upload-is-not-allowed

the stackoverflow link said to add “text/plain” in config/mime .php

so the config become

 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel','text/plain'),

it solve my problem

htaccess codeigniter in subfolder

i have codeigniter in subfolder, the url is

http://192.168.0.80/suropati-dashboard/index.php/login

remove index.php so i get url

http://192.168.0.80/suropati-dashboard/login

but it stuck with .htaccess config, this how to solve

server using ubuntu server 15.10

first create dir for logs, this is optional, i using this folder to file log file

mkdir -p /var/www/logs

second edit /etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>
        ServerAdmin g3n1k@x230
        DocumentRoot /var/www/html/
        <Directory />
                Options Indexes FollowSymLinks
                AllowOverride All
        </Directory>
        <Directory /var/www/html/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
        ErrorLog /var/www/logs/error_log
        CustomLog /var/www/logs/custom_log combined
        RewriteEngine On
</VirtualHost>

third edit .htaccess in sub folder /var/www/html/suropati-dashboard/.htaccess

RewriteEngine On
RewriteBase /suropati-dashboard/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

last restart service apache2

sudo service apache2 restart

codeigniter sub folder remove index.php with .htaccess

edit file /etc/apache2/apache2.conf


sudo nano /etc/apache2/apache2.conf

in default root directory, ex /var/www


<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

edit to

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

and make .htaccess file in codeigniter sub project/folder

let say our sub folder is /var/www/html/project1

nano /var/www/html/project1/.htaccess

and copy this code to .htaccess

RewriteEngine On
RewriteBase /project1/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]

restart apache

sudo service apache2 restart