PHP Cache

When working on PHP websites made from scratch and without a framework, speed can often be an issue. Caching is extremely useful in order to speed up PHP webpages.

  • file cache
  • memcached/redis
  • APC

Each used for slightly different goal.

File cache is usually something that you utilize when you can pre-render files or parts of them. It is used in templating solutions, partial views (mvc), css frameworks. That sort of stuff.

Memcached and redis are both more or less equal, except redis is more of a noSQL oriented thing. They are used for distributed cache ( multiple servers , same cached data ) and for storing the sessions, if you have cluster of webservers.

APC is good for two things: opcode cache and data cache. Faster then memcached, but works for each server separately.


Bottom line is : in a huge project you will use all of them. Each for a different task.

how to make a simple PHP caching system for your web pages.

Page Caching

1.create a first file for caching (first-cache.php)



$url = $_SERVER["SCRIPT_NAME"];
$break = Explode('/', $url);
$file = $break[count($break) - 1];
$cachefile = 'cached-'.substr_replace($file ,"",-4).'.html';
$cachetime = 18000;
// Serve from the cache if it is younger than $cachetime
if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
echo "\n";
readfile($cachefile);
exit;
}
ob_start(); // Start the output buffer
?>
  • The first five lines create the cached file name according to the current PHP file
  • Line six creates a $cachetime variable, which determines the life of our simple cache (Cachefile time).
  • Lines nine to thirteen are a conditional statement which looks for a cache file named $cachefile. If the file is found, a comment is inserted (line ten) and the $cachefile file is included. Then, the exit statement stops the execution of the script and the file is sent to the client browser. This means that if a static file is found, no PHP is interpreted by the server.
  • Line 14 creates a buffer if the $cachefile file isn’t found.

2.create another new PHP file (second-cache.php)


// Cache the contents to a cache file
$cached = fopen($cachefile, 'w');
fwrite($cached, ob_get_contents());
fclose($cached);
ob_end_flush(); // Send the output to the browser

If a cached file named $cachefile (first-cache.php) isn’t found on your server, this code will be executed and will create the cache file itself.

3.Include Cache Files On Your Page

the first-cache.php file must be included at the beginning of your PHP page and the second-cache.php at the end, as shown below:

include('first-cache.php'); 
// Your regular PHP code goes here
include('second-cache.php');

As a result, next time the page will be requested, the $cachefile static file will be served to the client browser instead of executing the whole PHP file.

What is OpCode Cache?

An OpCode cache is a performance-enhancing extension that caches the result of the PHP code compilation to bytecode. Throughout PHP’s lifetime, there have been a number of OpCode caches available, mostly depending on the used PHP version.

How Do I Enable OpCode Cache?

As available OpCode caches depend on the PHP version used on your server, please get in touch with your web hosting provider to see how to enable OpCode caching on your site.

drupal 8 form custom client side validation

//for translation
var noHtmlMessage= Drupal.t('No HTML tags are allowed!');

//adding new method to validate function 
//html tag validation
jQuery.validator.addMethod("noHTML", function(value, element) {
  return this.optional(element) || /^([a-z0-9]+)$/.test(value);
}, noHtmlMessage);

var enterRequered= Drupal.t('Please enter required field');
// Validation rules
$requredRule = {
    required: false,
    noHTML: true,
    messages: {
        required: enterRequered,
    }
};

//create a dummy button for this custom client side validation and if form is valid click to origin form submit button
//add jquery validation js

$('#views-exposed-form-tariff-finder-page-1 #custom-submit-tariff-finder', context).on('click', function () {
    $("#views-exposed-form-tariff-finder-page-1", context).validate({
    });
    $("#views-exposed-form-tariff-finder-page-1 input[name=name]", context).rules("add", $requredRule);
    if ($("#views-exposed-form-tariff-finder-page-1", context).valid()) {
      $(".submitWrapper input", context).click();
    }
});

Drupal Security

Follow the recommendations below to harden your Drupal security.

1.Keep Drupal and modules up to date
2.Use smart usernames and passwords
Don’t user “admin” as your username and choose a complex password
3.Use Drupal security modules

  • Login Security: Limit number of login attempts and deny access by IP address.
  • ACL: Access control lists for access to nodes.
  • Password policy: Define more security password policies for users.
  • Captcha: Block form submissions from spambots/scripts.
  • Automated Logout: Allows administrator ability to log out users after specified time period.
  • Session Limit: Limit the number of simultaneous sessions per user.
  • Content Access: Permissions for content types by role and author.
  • Coder: Checks your Drupal code against coding standard and best practices.
  • SpamSpan filter: Obfuscates email address to help prevent spambots from collecting them.
  • Hacked!: Check to see if there have been changes to Drupal core or themes.

4.Block bad bots
There are always bad bots, scrapers, and crawlers hitting your Drupal sites and stealing your bandwidth.Many of the security modules mentioned above can work great to block bad bots, but sometimes you might need to do this at the server level.If you wanted to block multiple User-Agent strings at once, you could add the following to your .htaccess file.

RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^.*(agent1|Wget|Catall Spider).*$ [NC]
RewriteRule .* - [F,L]

5. Always use secure connections
No matter where you are you should always trying to ensure the connections you are using are secure. You should use SFTP encryption if your web host provides it, or SSH. If you are using an FTP client the default port for SFTP is usually 22.

6. Check file permissions
7. Block access to important files

<FilesMatch "^(authorize|cron|install|upgrade)\.php">
    Order deny, allow
    deny from all
    Allow from 127.0.0.1
</FilesMatch>

8. Database security
The first thing we recommend is using a different table prefix. If you change this to something like x3sdf_ it will make it much harder to guess by an intruder and help prevent SQL injections.
9. SSL certificate
10. Harden HTTP security headers
HTTP security headers provide yet another layer of security for your Drupal site by helping to mitigate attacks and security vulnerabilities.

Use the below module for this :: Security Kit

Note :: Make sure your local development .htaccess file changes is added in the live .htaccess file ( if  .htaccess file is already in .gitignore

iOS Push Notifications using Apple Push notification service

public function pushNotification($deviceToken, $message)
    {
    
        $passphrase = "bfl001";

        // Put your alert message here:
        // $message = 'My first push notification';

        $ctx = stream_context_create();
        // get your .pem file from apple itunes related to your project
        stream_context_set_option($ctx, 'ssl', 'local_cert', $this->rootPath.'/pushcert.pem');
        stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

        // Open a connection to the APNS server
        //$pushGateway = 'ssl://gateway.sandbox.push.apple.com:2195';
        $pushGateway = 'ssl://gateway.push.apple.com:2195';
        $fp = stream_socket_client($pushGateway, $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);
        if (!$fp) {
            exit("Failed to connect: $err $errstr" . PHP_EOL);
        }

        //echo 'Connected to APNS' . PHP_EOL;
        // Create the payload body
        $body['aps'] = array(
          'alert' => $message,
          'sound' => 'notify.m4a'
        );

        // Encode the payload as JSON
        $payload = json_encode($body);

        // Build the binary notification
        $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

        // Send it to the server
        $result = fwrite($fp, $msg, strlen($msg));

        // if (!$result) {
        //     echo 'Message not delivered' . PHP_EOL;
        // } else {
        //     echo 'Message successfully delivered' . PHP_EOL;
        // }
        // Close the connection to the server
        PHP_EOL;
        fclose($fp);
    }

Android Push Notifications using Firebase Cloud Messaging (FCM), PHP

public function fcmNotification($deviceToken, $msg)
    {
        #API access key from Google API's Console
        define('API_ACCESS_KEY', 'your_access_key_here');
        $registrationIds = $deviceToken;
        $fields = array(
            'to' => $registrationIds,
            "priority" => 'high',
            "notification"=>$msg,
            "data"=>$msg,
        );

        $headers = array(
            'Authorization: key=' . API_ACCESS_KEY,
            'Content-Type: application/json'
        );
        #Send Reponse To FireBase Server
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
        $result = curl_exec($ch);
        curl_close($ch);
        #Echo Result Of FireBase Server
        //  echo $result;
    }

Firebase User Create using php (Curl)

$dataCurlPost = array(
    "email"=> test@email.com,
    "password" => "abc123",
    "returnSecureToken"=> true
);
$data_string = json_encode($dataCurlPost);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=AHDJDKADSFASDKFDSUAFNASDFASDFKJADS');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data_string))
);
$responseMessenger = curl_exec($ch);
curl_close($ch);
$dataResponseMessenger = json_decode($responseMessenger, true);
return $dataResponseMessenger;   

PHP Firestore(Firebase) :: Saving Data to a cloud firestore database using php (Curl)

Add data to Cloud Firestore Use the Cloud Firestore REST API

Making REST calls

All REST API endpoints exist under the base URL https://firestore.googleapis.com/v1/.

To create a path to a document with the ID LA in the collection cities under the project YOUR_PROJECT_ID you would use the following structure.

/projects/YOUR_PROJECT_ID/databases/(default)/documents/cities/LA

To interact with this path, combine it with the base API URL.

https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/cities/LA

Refer the below sample

    $firestore_data  = [
        "orderName" => ["stringValue" => "ordering"],
        "userId" => ["integerValue" =>12],
        "bloodRequestId" => ["integerValue" =>200],
        "acceptCount" => ["integerValue" =>1],
    ];
    $data = ["fields" => (object)$firestore_data];

    //    Possible *value options are:
    //    stringValue
    //    doubleValue
    //    integerValue
    //    booleanValue
    //    arrayValue
    //    bytesValue
    //    geoPointValue
    //    mapValue
    //    nullValue
    //    referenceValue
    //    timestampValue

    $json = json_encode($data);
    $Enter your firestore unique key: below is a sample
    $firestore_key = "ASDFDSAFASFVCEYDDEHHFF";
    #Provide your firestore project ID Here
    $project_id = "Blood-requset-orders";

    $object_unique_id = random_int(1,300);

    $url = "https://firestore.googleapis.com/v1beta1/projects/dough-man-orders/databases/(default)/documents/orders/".$object_unique_id;

    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_HTTPHEADER => array('Content-Type: application/json',
            'Content-Length: ' . strlen($json),
            'X-HTTP-Method-Override: PATCH'),
        CURLOPT_URL => $url . '?key='.$firestore_key,
        CURLOPT_USERAGENT => 'cURL',
        CURLOPT_POSTFIELDS => $json
    ));

    $response = curl_exec( $curl );

    curl_close( $curl );

    // Show result
    echo $response . "\n";

File handling in Linux

# command to change ownership of files

sudo chown : -R 

Eg: sudo chown name:name -R /var/www/html/

# command to change permission of files

sudo chmod 755 -R /var/www/html/

# command to move a file

sudo mv {old-file with location} {new-file with location} 

// eg:/var/www/public_html/hyn

# To rename a file can do the above technique

sudo mv {old-file-name} {new-file-name}

# command to copy, delete a file in linux

sudo cp -i -r /media/projects/hyn007 /var/www/html/hyn
rm {file-name}

# zip a folder with todays date

zip -r "archive-$(date +"%Y-%m-%d").zip" 
E.g: zip -r /media/wip/Public/arb008-$(date +"%Y-%m-%d").zip web/sites/default/files/

# unzip a folder

unzip file.zip -d destination_folder

# Using ls to list directories and their total sizes

du -sh *