A quick introduction of .htaccess with examples

Posted: 27th October 2018 by azinkey in php
Tags: ,

What is .htaccess?

The .htaccess file is a configuration file that affects how a webserver responds to various requests.

Why is it called .htaccess?

(Hyper Text + Access) These files were first used to control user access on a per-directory basis.

Where is the .htaccess file?

every folder (directory) on your server could have one

Why can’t I find my .htaccess file?

On most file systems, file names that begin with a dot ( . ) are hidden files. This means they are not typically visible by default.

Request Status

    200     OK
    300-        Redirect
    400-        Client
    500-        Server
Client Request Errors

    400 — Bad Request

    401 — Authorization Required

    402 — Payment Required (not used yet)

    403 — Forbidden

    404 — Not Found

    405 — Method Not Allowed

    406 — Not Acceptable (encoding)

    407 — Proxy Authentication Required

    408 — Request Timed Out

    409 — Conflicting Request

    410 — Gone

    411 — Content Length Required

    412 — Precondition Failed

    413 — Request Entity Too Long

    414 — Request URI Too Long

    415 — Unsupported Media Type.
Server Errors

    500 — Internal Server Error

    501 — Not Implemented

    502 — Bad Gateway

    503 — Service Unavailable

    504 — Gateway Timeout

    505 — HTTP Version Not Supported.

URL Redirects and URL Rewriting

301 vs. 302
301 means “Permanently Moved”
302 means “Moved Temporarily”

Redirect vs. Rewrite
#Basic Page Redirect
Redirect 301 /relative-url.html http://example.com/full-url.html
#Redirecting a large section
Redirect 301 /old-directory http://example.com/new-directory
#Redirecting an entire site
Redirect 301 / http://newurl.com
#Redirecting www to non-www
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{http_host} ^www\.example\.com [NC]
RewriteRule ^(.*)$ http://example.org/$1 [R=301,NC]
#Redirecting to www
RewriteEngine On
RewriteCond %{http_host} ^example.com [NC
RewriteRule ^(.*) http://www.website.com/$1 [R=301,NC]

Hiding Your .htaccess File

order allow,deny
deny from all

Magick things happend with .htaccess

1. Stopping hot linking of images:

    #Block hotlinking
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?mydomain.com [NC]
    RewriteRule \.(jpg|jpeg|png|gif|css)$ - [NC,F,L]

2. Block bad crawlers

#To block an IP address
RewriteCond %{REMOTE_HOST} [OR]
#To block user-agents
RewriteCond %{HTTP_USER_AGENT} ^Zeus [NC,OR]

RewriteRule ^.* - [F,L]
#or Blacklisting by IP

order allow,deny
deny from
deny from 789.56.4.
allow from all
#or Whitelisting by IP

order deny,allow
deny from all
allow from
allow from 789.56.4.7
#or Domain names instead of IP addresses

order allow,deny
deny from example.com
allow from all

3. Optimize the performance of your site


     AddOutputFilterByType DEFLATE text/html text/plain text/css application/json
     AddOutputFilterByType DEFLATE application/javascript
     AddOutputFilterByType DEFLATE text/xml application/xml text/x-component
     AddOutputFilterByType DEFLATE application/xhtml+xml application/rss+xml application/atom+xml
     AddOutputFilterByType DEFLATE image/x-icon image/svg+xml application/vnd.ms-fontobject application/x-font-ttf font/opentype

#Max-age expires:

# If you don't use filenames to version, lower the CSS  and JS to something like

ExpiresActive on
# Perhaps better to whitelist expires rules? Perhaps.

ExpiresDefault                          "access plus 1 month"

# cache.appcache needs re-requests in FF 3.6 (thanks Remy ~Introducing HTML5)
ExpiresByType text/cache-manifest       "access plus 0 seconds"

# Your document html
ExpiresByType text/html                 "access plus 0 seconds"

# Data
ExpiresByType text/xml                  "access plus 0 seconds"
ExpiresByType application/xml           "access plus 0 seconds"
ExpiresByType application/json          "access plus 0 seconds"

# Feed
ExpiresByType application/rss+xml       "access plus 1 hour"
ExpiresByType application/atom+xml      "access plus 1 hour"

# Favicon (cannot be renamed)
ExpiresByType image/x-icon              "access plus 1 week"

# Media: images, video, audio
ExpiresByType image/gif                 "access plus 1 month"
ExpiresByType image/png                 "access plus 1 month"
ExpiresByType image/jpeg                "access plus 1 month"
ExpiresByType video/mp4                 "access plus 1 month"

# Webfonts
ExpiresByType application/x-font-ttf    "access plus 1 month"
ExpiresByType font/opentype             "access plus 1 month"
ExpiresByType application/x-font-woff   "access plus 1 month"
ExpiresByType image/svg+xml             "access plus 1 month"
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"

# CSS and JavaScript
ExpiresByType text/css                  "access plus 1 year"
ExpiresByType application/javascript    "access plus 1 year"

4. Fix broken links, preserve SEO

Redirect /pdf_press /products/pdf-press
5. Custom error pages

ErrorDocument 404 /error/error404.htm
ErrorDocument 500 /error/error500.htm

6. Require SSL

# require SSL
SSLOptions +StrictRequire
SSLRequire %{HTTP_HOST} eq "domain.tld"
ErrorDocument 403 https://domain.tld

# require SSL without mod_ssl
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
7. Setting Environment Variables

SetEnv SPECIAL_PATH /foo/bin

8. Password Protection With .htpasswd

#Usernames and passwords for the .htaccess system are stored in a file name .htpasswd
#These are stored each on a single line, in the form:


AuthUserFile /usr/local/etc/.htpasswd
AuthName "Name of Secure Area"
AuthType Basic

require valid-user

You can also put users into groups and allow access based on group. This is done by adding another file which specifies the groups.

The group file, which could be named (for example) .htgroups looks like this:

admin: johnsmith janedoe
staff: jackdoe cindysmith

Then you can specify it in your .htaccess file:

AuthUserFile /usr/local/etc/.htpasswd
AuthGroupFile /usr/local/etc/.htgroup
AuthName "Admin Area"
AuthType Basic

require group admin

9. Block Users by Referrer

RewriteEngine on
RewriteCond %{HTTP_REFERER} ^http://.*example\.com [NC,OR]
RewriteRule .* - [F] 

10. Specifying a Default File for a Directory

DirectoryIndex home.html

11. Force Download by MIME Type

AddType application/octet-stream pdf doc docx rtf

12. Disable or Enable Index

#Disabling Indexes
Options -Indexes

#Enabling Indexes
Options +Indexes

#Hiding some files from the Index
IndexIgnore *.gif *.jpg
IndexIgnore secret-image.jpg

13. Scripts as Source pre

RemoveHandler cgi-script .php .py
AddType text/plain .php .py

14. Configuring PHP Settings

php_value upload_max_filesize  10M

more coming soon…


First you need to check whether the user or data is exits or not. then you can perform the update and insert operation.
$q = $this->db->get(‘profile’);

if ( $q->num_rows() > 0 )
} else {
$this->db->set(‘user_id’, $id);

There is one more way by using mysql query
$query = ‘INSERT INTO table_name (id, name) VALUES (?, ?)

Suppose this is the table.

| id | name |
| 1 | Urfusion |
| 2 | Christian|

now we are performing ON DUPLICATE KEY UPDATE

INSERT INTO table_name VALUES (3,’Example’) ON DUPLICATE KEY UPDATE name=’Example’;

result is

| id | name |
| 1 | Urfusion |
| 2 | Christian|
| 3 | Example |

Example has been inserted into the table because there is no entry with the key id is there now if we are trying to insert data on the position 1 or 2 then
INSERT INTO table_name VALUES (1,’Name_changed’) ON DUPLICATE KEY UPDATE name=’Name_changed’;

The result is

| id | name |
| 1 | Name_changed|
| 2 | Christian |
| 3 | Example |


Suppose you have approx 1000 image files for download, then here is a command to download all them.

  1. Create a text file named it urls.txt
  2. enter all urls each url in a new line
  3. type WGET -i urls.txt in your terminal

WGET -i urls.txt

CakePHP in a subdirectory using nginx

Posted: 10th August 2017 by admin in php
Tags: , , , , ,

CakePHP in a subdirectory using nginx

cakephp subdirectory nginx

I was facing many issues in setup cakephp3 in subfolder on nginx server.

I was doing changes in new server config while we have to do that in existing server config(well that work for me :) )


cakephp subdirectory nginx

cakephp subdirectory nginx


So I just add following in default config file. Which can be found /etc/nginx/sites-available

location /youproj{
alias /usr/share/nginx/html/public_html/youproj/webroot;
if (-f $request_filename) {

prevent recursion

if ($request_uri ~ /webroot/index.php) {

rewrite ^/youproj$ /youproj/ permanent;
rewrite ^/youproj/webroot/(.) /youproj/webroot/index.php?url=$1 last;
rewrite ^/youproj/(.
)$ /youproj/webroot/$1 last;


And enable base_url in app.php in config folder of cakephp
'App' => [
'namespace' => 'App',
'encoding' => env('APP_ENCODING', 'UTF-8'),
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'),
'base' => false,
'dir' => 'src',
'webroot' => 'webroot',
'wwwRoot' => WWW_ROOT,
'baseUrl' => env('SCRIPT_NAME'),
'base' => '/mamonde',
'fullBaseUrl' => false,
'imageBaseUrl' => 'img/',
'cssBaseUrl' => 'css/',
'jsBaseUrl' => 'js/',
'paths' => [
'plugins' => [ROOT . DS . 'plugins' . DS],
'templates' => [APP . 'Template' . DS],
'locales' => [APP . 'Locale' . DS],




Codility brackets opening closing.

codility brackets opening closing.

codility you are given a string s consisting of n brackets opening problem solution.

codility brackets opening closing

codility brackets opening closing

function isBalanced($str){
$count = 0;
$ocount = 0;
$ccount = 0;
$length = strlen($str);
for($i = 0; $i < $length; $i++){
if($str[$i] == '(')
$ocount += 1;
else if($str[$i] == ')')
$ccount += 1;
if($ccount == $ocount){
$count = $ocount;
$count = $ccount;
return $count;
echo isBalanced("))");


Hey, Today we learn how to send push notification for android in php.

First create a class with following code


class Pusher{
const GOOGLE_GCM_URL = 'https://android.googleapis.com/gcm/send';
private $apiKey;
private $proxy;
private $output;
public function __construct($apiKey, $proxy = null)
$this->apiKey = 'your_key';
$this->proxy = $proxy;
* @param string|array $regIds
* @param string $data
* @throws Exception
public function notify($regIds, $data)
// pr($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::GOOGLE_GCM_URL);
if (!is_null($this->proxy)) {
curl_setopt($ch, CURLOPT_PROXY, $this->proxy);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->getPostFields($regIds, $data));
$result = curl_exec($ch);
if ($result === false) {
throw new Exception(curl_error($ch));
// pr($result); die;
$this->output = $result;
return $result;
* @return array
public function getOutputAsArray()
return json_decode($this->output, true);
* @return object
public function getOutputAsObject()
return json_decode($this->output);

private function getHeaders(){
    return [
        'Authorization: key=' . $this-&gt;apiKey,
        'Content-Type: application/json'

private function getPostFields($regIds, $data){
    $fields = [
        'registration_ids' =&gt; is_string($regIds) ? [$regIds] : $regIds,
        'data'             =&gt; is_string($data) ? ['message' =&gt; $data] : $data,


now call your notify function by creating a object of pusher class.

$notification = array("title" => $title,
"message" => $message,
"data" => $data,

$pusher = new Pusher($apiKey);
$pusher->notify($reg_ids, $notification); // reg_ids are the device ids on which you want to send push

If you are using cakephp or any other php framework then add pusher class in you plugin folder(appPluginPusherPusher.php) and load it where you want to use.

Push notification IOS

Posted: 13th February 2017 by admin in Iphone, php
Tags: , , , , , ,

Push notification IOS


// authentication
$host = "localhost";
$user = "user";
$pass = "pass";
$dbname = "DB";

// create connection with database
$con = mysql_connect($host, $user, $pass);

// check whether database connection is successful
if (!$con) {
// if connection not successful then stop the script and show the error
die('Could not connect to database: ' . mysql_error());
} else {
// if database connection successful then select the database
mysql_select_db($dbname, $con);

// get the id, token from database
$query = "SELECT notifications.id as pid, notifications.by_userid, notifications.userid, notifications.messege, notifications.is_read, users.id, users.name, users.email, users.dob, users.gender, users.profile_pic, users.device_id FROM table.notifications AS notifications INNER JOIN table2.users AS users ON (notifications.userid = users.id) WHERE notifications.is_read = '0' ";
$result = mysql_query($query);
$data = mysql_fetch_array($result);
$count = count($data);

//Setup notification message
$body = array();
$body['aps'] = array('alert' => $data['messege']);
$body['aps']['notifurl'] = 'yourwebsite.com/push_new.php';
$body['aps']['badge'] = $count;
$body['aps']['messege'] = $data['messege'];
$body['aps']['id'] = $data['pid'];
$id = $data['pid'];

//Setup stream (connect to Apple Push Server)
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'passphrase', '123456');
stream_context_set_option($ctx, 'ssl', 'local_cert', 'certificate.pem'); // add your .pem file
$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
stream_set_blocking($fp, 0);
// This allows fread() to return right away when there are no errors. But it can also miss errors during
// last seconds of sending, as there is a delay before error is returned. Workaround is to pause briefly
// AFTER sending last notification, and then do one more fread() to see if anything else is there.

if (!$fp) {
echo "Failed to connect (stream_socket_client): $err $errstrn";
} else {

// Keep push alive (waiting for delivery) for 90 days
$apple_expiry = time() + (90 * 24 * 60 * 60);

// Loop thru tokens from database
while ($row = mysql_fetch_array($result)) {
$apple_identifier = $row["id"];
$deviceToken = $row['device_id'];
$payload = json_encode($body);

// Enhanced Notification
$msg = pack("C", 1) . pack("N", $apple_identifier) . pack("N", $apple_expiry) . pack("n", 32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n", strlen($payload)) . $payload;

fwrite($fp, $msg);

// We can check if an error has been returned while we are sending, but we also need to
// check once more after we are done sending in case there was a delay with error response.

// Workaround to check if there were any errors during the last seconds of sending.
// Pause for half a second.
// Note I tested this with up to a 5 minute pause, and the error message was still available to be retrieved


echo 'Completed';
$query = "UPDATE `notifications` SET `is_read` = 1 WHERE id = $id ";
$results = mysql_query($query);


// FUNCTION to check if there is an error response from Apple
// Returns TRUE if there was and FALSE if there was not
function checkAppleErrorResponse($fp) {

//byte1=always 8, byte2=StatusCode, bytes3,4,5,6=identifier(rowID).
// Should return nothing if OK.
//NOTE: Make sure you set stream_set_blocking($fp, 0) or else fread will pause your script and wait
// forever when there is no response to be sent.

$apple_error_response = fread($fp, 6);

if ($apple_error_response) {

// unpack the error response (first byte 'command" should always be 8)
$error_response = unpack('Ccommand/Cstatus_code/Nidentifier', $apple_error_response);

    if ($error_response['status_code'] == '0') {
        $error_response['status_code'] = '0-No errors encountered';
    } else if ($error_response['status_code'] == '1') {
        $error_response['status_code'] = '1-Processing error';
    } else if ($error_response['status_code'] == '2') {
        $error_response['status_code'] = '2-Missing device token';
    } else if ($error_response['status_code'] == '3') {
        $error_response['status_code'] = '3-Missing topic';
    } else if ($error_response['status_code'] == '4') {
        $error_response['status_code'] = '4-Missing payload';
    } else if ($error_response['status_code'] == '5') {
        $error_response['status_code'] = '5-Invalid token size';
    } else if ($error_response['status_code'] == '6') {
        $error_response['status_code'] = '6-Invalid topic size';
    } else if ($error_response['status_code'] == '7') {
        $error_response['status_code'] = '7-Invalid payload size';
    } else if ($error_response['status_code'] == '8') {
        $error_response['status_code'] = '8-Invalid token';
    } else if ($error_response['status_code'] == '255') {
        $error_response['status_code'] = '255-None (unknown)';
    } else {
        $error_response['status_code'] = $error_response['status_code'] . '-Not listed';

    echo '&lt;br&gt;&lt;b&gt;+ + + + + + ERROR&lt;/b&gt; Response Command:&lt;b&gt;' . $error_response['command'] . '&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Identifier:&lt;b&gt;' . $error_response['identifier'] . '&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Status:&lt;b&gt;' . $error_response['status_code'] . '&lt;/b&gt;&lt;br&gt;';

    echo 'Identifier is the rowID (index) in the database that caused the problem, and Apple will disconnect you from server. To continue sending Push Notifications, just start at the next rowID after this Identifier.&lt;br&gt;';

    return true;

return false;



Email template optimization tools

Posted: 13th January 2017 by admin in Uncategorized
Tags: , , , ,
Email template optimization tools

Email template optimization tools


Here is the list of email templates optimization tools. Remember to exclude media query if you have for responsive design. They will not work properly if inline. Some time might face a problem that your responsive design is not working on some of the email clients. The reason might be of character limit. The stylesheet is then checked against a 8,192 character limit. If your stylesheet, after processing, exceeds the limit, the whole stylesheet gets removed from your email.



configure ejabberd xmpp ubuntu server part 2

In First Tutorial we have configure ejabberd XMPP with default menisa database . now in this tutorial i will explain how to configure ejabberd with MySql .


configure ejabberd xmpp ubuntu server part 2

configure ejabberd xmpp ubuntu server part 2


Step 1 :  Open etc/ejabberd/ejabberd.cfg file and comment following line :

{auth_method, internal}.

and add the following line in file :

{auth_method, odbc}.
{odbc_server, {mysql, “server”, “database name”, “username”, “password”}}.


  1. server : your mysql server ip
  2. user name and password : database access username and password .

Step 2 :

Now you need to configure mysql on server . so for that you need to install SVN on Ubuntu server by following command :
sudo apt-get install subversion

after installation of SVN you need to download MySql module.

  1. first create a directory  using mkdir command
  2. download following package  http://svn.process-one.net/ejabberd-modules/mysql/trunk/ by using below command : svn co http://svn.process-one.net/ejabberd-modules/mysql/trunk/
  3. after download  run /.build.sh c file . it will generate following beam file  in ebin folder





  4. Please copy below file into  ejabberd ebin directory  /usr/lib/ejabberd/ebin this folder .
  5.  now open etc/ejabberd/ejabberd.cfg  file and do following changes
  • Change mod_last to mod_last_odbc to store the last seen date in MySQL.

  •  Change mod_offline to mod_offline_odbc to store offline messages in MySQL.

  • Change mod_roster to mod_roster_odbc to store contact lists in MySQL.

  •  Change mod_private to mod_private_odbc to store user private XML storage in MySQL.

  •   Change mod_privacy to mod_privacy_odbc to store user privacy lists in MySQL.

  •  Change mod_pubsub to mod_pubsub_odbc to store PubSub nodes, items and subscriptions in MySQL.

  •   Change mod_vcard to mod_vcard_odbc to store user description in MySQL.

Step 3 :

  1. Now Login in mySql Database and create a database “ejabberd
  2. Now download ejabberd MySql table schema folloing command   wget https://raw.githubusercontent.com/processone/ejabberd/master/sql/mysql.sql
  3. Now import this file in recently created “ejabberd” database.
  4. For installing mod_archive (for saving chat in DB)
    svn co https://svn.process-one.net/ejabberd-modules
    cd ejabberd-modules/mod_archive/trunk
    ./build.sh (If this step gives an error install erlang-nox package)
    copy ebin/* beam files in ejabberd ebin directory( /usr/lib/ejabberd/ebin)

  5. now go to this directory ejabberd-modules/mod_archive/trunk/src/ here you will find  this “mod_archive_odbc_mysql.sql” my sql file , you need to import this file in recently created database “ejabberd
  6. In /etc/ejabberd/ejabberd.cfg add mod_archive_odbc module
    {mod_archive_odbc, [{database_type, "mysql"},
    {default_auto_save, true},
    {enforce_default_auto_save, true},
    {default_expire, infinity},
    {enforce_min_expire, 0},
    {enforce_max_expire, infinity},
    {replication_expire, 31536000},
    {session_duration, 1800},
    {wipeout_interval, 86400}]},

    sudo service ejabberd restart


Now you have configured Ejabberd with MySql

if you need any assistance please comment ..

Configure ejabberd xmpp ubuntu server


configure ejabberd xmpp ubuntu server

configure ejabberd xmpp ubuntu server


After facing so many issues and investing so many hours I write below steps for configure ejabberd. In first tourial we learn how to configure ejabbere on AWS EC 2 Ubuntu server. In second tutorial we will configure it with mysql.

Step 1: First Update Ubuntu Server  with following commands

sudo apt-get update        # Fetches the list of available updates
sudo apt-get upgrade       # Strictly upgrades the current packages
sudo apt-get dist-upgrade  # Installs updates (new ones)

 Step 2: sudo apt-get install ejabberd– this command will install ejabberd  on ubuntu machine.

Step 3: After complete installation of ejabberd , you need to register a user , you can register user below command

ejabberdctl register admin XXX.com password

Here admin — user name of user

XXX.com  – your domain name

password : user password

if above command show error then you need to register user with localhost domain .

ejabberdctl register admin localhost password

Step 4 : After successfully registration of  user , you can edit domain in ejabberd.cfg (ejabberd Configuration file) , path of this file is /etc/ejabberd/ejabberd.cfg . now you can open this file using vi  editor sudo vi ejabberd.cfg. 

now you can search below section and edit with you domain name

%% Admin user
{acl, admin, {user, "admin", "xxx.com"}}.

%% Hostname
{hosts, ["xxx.com"]}.

Now restart ejabberd server with following command sudo service ejabberd restart

if this command didn’t work then you can start ejabberd server by alternative command sudo /etc/init.d/ejabberd start

Step 5 : Now you can check server is running by hitting below URL : http://xxx.com:5280/admin  (here xxx.com is your domain name )

if above url is not loaded  i.e. ejabberd server is not started  , then please check status of ejabberd sudo service ejabberd status

if it shows  server is  already stopped then you can run sudo service ejabbered startn 

or or sudo /etc/init.d/ejabberd start

if this didn’t work then you can run following command sequentially for stop ejabberd server on any node

1. sudo /etc/init.d/ejabberd stop  - to stop ejabberd 
2. sudo killall ejabberd  -  kill all ejabberd process 
3. sudo killall beam - kill all beam process
4. sudo killall epmd
5. sudo service apache2 restart
6. sudo service ejabberd start  or sudo /etc/init.d/ejabberd start


Step 6 : now repeat step 5 again and enter user name and password that you have registered by running this command  ejabberdctl register admin localhost password

user name : admin@xxx.com

password : password


Step 7 :  Now you can test ejjaberd XMPP on server using any XMPP client like pidgin .