Tuesday, September 25, 2018

Few Notes about TCPDF - An Open Source PHP class for generating PDF documents

Few Notes about TCPDF - An Open Source PHP class for generating PDF documents

TCPDF is an open source PHP class for generating PDF documents. It is easy to install and setup as well as many options available. There are few things worth to be noticed in my experience of usage. Here are some:

1. Installation

To install TCPDF class is easy.

  1. Download all files from TCPDF’s github.
  2. Create a directory class under the main directory of the Site.
  3. Create a directory class/tcpdf.
  4. Copy all files to class/tcpdf.
  5. Add a line of code in the beginning of the php file:
    require_once "class/tcpdf/tcpdf.php";
  6. Have fun!

2. Traditional Chinese support

The default setting of TCPDF does not support Traditional Chinese character because it lacks of fonts in Traditional Chinese. We have to add the font files manually.

  1. Download font file ‘Droid Sans Fallback’ and ‘msungstdlight’.
  2. Add two font files to class/tcpdf/fonts.
  3. Open config/tcpdf_config.php and change two settings:
    define ('PDF_FONT_NAME_MAIN', 'helvetica');
       to
    define ('PDF_FONT_NAME_MAIN', 'msungstdlight');
    
    define ('PDF_FONT_NAME_DATA', 'helvetica');
    	to
    define ('PDF_FONT_NAME_DATA', 'msungstdlight');
    

p.s Here explains how to generate TrueTypeUnicode font files from DroidSansFallback.ttf font file.

3. A bug fixed while using PHP 7.2

When using PHP 7.2, TCPDF version 6.2.12 shows the error message:

Deprecated: The each() function is deprecated. 
This message will be suppressed on further calls in /Users/xxx/Sites/mini_shop/class/tcpdf/tcpdf.php on line 16544
  
TCPDF ERROR: Some data has already been output, 
can't send PDF file

Since each() function is deprecated after PHP version 7.2, the code must be modified in order to fit the new version. Fortunately, somebody has posted the solution. It works again just to replace three lines of code in tcpdf.php as follows:

-  while (list($key, $val) = each($prop)) {
+  foreach($prop as $key => $val) {
-  while (list($id, $name) = each($attr_array[1])) {
+  foreach($attr_array[1] as $id => $name) {
-  while (list($id, $name) = each($style_array[1])) {
+  foreach($style_array[1] as $id => $name) {

Replace each() function with foreach() function, and that’s it!

Sunday, September 23, 2018

A Simple CRUD App in PHP

A Simple CRUD App in PHP
The “CRUD” means Create, Read, Update, Delete and is the most frequent functions used in daily operation. Here shows a simple CRUD app in PHP for reference. Let’s follow the methods explained in the article of my blog “Building PHP Web Apps Without Framework” and start to build a product list web site.

Seven Basic Operations

There are seven operations need to identified. They are:
  1. list_products: get and show all products.
  2. show_product: get product data for a specific prod_id.
  3. new_product: get a new form to enter product data.
  4. create_product: create a product and save to database.
  5. edit_product: get and edit product data for a specific prod_id.
  6. update_product update product data of a specific prod_id to database.
  7. delete_product delete product for a specific prod_id.
The operations 3 and 4 are consecutive steps, which mean when a user creates a product by finishing product data entry (operation 3), the system save product data to database at once (operation 4).
Likewise, operation 5 and 6 have the same situation. The system gets and shows the product data on the screen (operation 5), then it saves the data back to database while data has been edited by a user (operation 6).

The Flow Control in “index.php”

Here shows the flow control in “index.php” which variable “$op” decides the program flow.
switch ($op) {
  case 'show_product':
    show_product($prod_id);
    break;
  case 'new_product':
    new_product();
    break;
  case 'create_product':
    $prod_id = create_product();
    header("Location:index.php?op=show_product&prod_id={$prod_id}");
    exit;
    break;
  case 'edit_product':
    edit_product($prod_id);
    break;
  case 'update_product':
    update_product($prod_id);
    header("Location:index.php?op=show_product&prod_id={$prod_id}");
    exit;
    break;
  case 'delete_product':
    delete_products($prod_id);
    header("Location:index.php");
    exit;
    break;
  default:
    list_products($keyword);
    break;
}

Monday, September 17, 2018

Building PHP Web Apps Without Framework

Building PHP Web Apps Without Framework
Building a PHP web app using a framework such as Laravel, Symfony and CakePHP is a straight-forward job. Just arrange functions according to the rules set by the framework, programmers usually can get the job done. However, learning the framework itself is not a very easy task. There are a lot of concepts, ideas, knowledge to learn. Learning time is quite long.
What if to build a PHP web app without using a framework? Just utilizing few basic tools such as template engine, and setting up some rules for passing parameters between web pages, a simple PHP web app is easy to build. Let’s find out!

Setup A Circulation Mechanism of Web Pages

Normally, the entry point of a web is index.html, it is index.php if programmed by PHP. So we can identify the direction is:
index.php -> index.html -> user interaction
   ^                               | 
    \----------------------------- /
Which means the system redirects to index.html at the end of index.php. Any operation triggered by pressing a button at index.html will start running from index.php with or without parameters again. The according operation is executed depends on the parameters POSTED by the former index.html. After the required operation executed, the system redirects to index.html with some other parameters passed. The index.html shows the pages accordingly again. Then the circulation mechanism is built.

Passing Parameters - Smarty Template Engine

How to passing parameters between pages? The answer is Smarty Template Engine. Here is how:
  1. Download Smarty and stored in a subdirectory /smarty/lib.
  2. Place these two lines of code at the beginning of index.php.
    require_once('smarty/libs/Smarty.class.php');
    $smarty = new  Smarty;
    
  3. place code as follows at the end of index.php.
    $smarty->assign('op', $op);
    $smarty->display('index.html');
    
Notice that ‘op’ means operation parameter. It is used to control the program flow in order to execute the required operation.
The last line is to display index.html. Therefore the program flow goes to the html rendering part.

Starting Web Page

We start from index.php with default (no) parameter passing to index.html. And html pages is rendered by default.
Imaging that there is a link shown as follows:
<a href="index.php?op=list_products">
If we press the link, it goes back to index.php with ‘op=product_display’ parameter.
That is the user interaction designed for user to decide to at the web page. Now the system goes back to index.php.

The ‘op’ Parameter and Flow Control

The flow control of index.php is decided by the ‘op’ parameter. $op variable is initialized and copy value from the session variable $_REQUEST[‘op’].
$op = isset($_REQUEST['op']) ? filter_var($_REQUEST['op'], FILTER_SANITIZE_MAGIC_QUOTES) : '';
A flow control built by switch to decide which operation is made.
switch ($op) {
  case 'list_products':
    $op = "list_products";
    list_products();
    break;
      :
      :
  default:
 show_default();  
    break;  
}
Also, a function list_products() in index.php is made:
function  list_products() {
  global  $mysqli, $smarty;

  $products = "";
  $sql = "SELECT  *  FROM products";
  $result = $mysqli->query($sql) or die($mysqli->connect_error);
  $products = $result->fetch_all(MYSQLI_ASSOC);
  $smarty->assign('products', $products);
}
A variable $products is passed to index.html for rendering web page.

Flow Control in the Web Page

The index.html is composed by at least three parts of html files. They are ‘head part’, ‘main part’ and ‘foot part’. The ‘main part’ is the place where flow control works. The following Smarty code acts as the control part. The system include list_products.html while $op == 'list_products', where shows all products.
<!DOCTYPE html>
<html lang="en">
  <head>
       :
  </head>
  <body>
    {if $op == 'list_products'}
   {include file = "list_products.html"}
    {elseif}
       :
    :
    {else}
       :  
    {/if}
       :
       :
  </body>
</html>
The sample code of list_products.html is as follows:
<div class="row">
  {foreach from=$products item=product}
    <img src="uploads/thumbs/{$product.prod_id}.png"  alt="{$product.prod_name}">
    <a href="index.php?prod_id={$product.prod_id}">{$product.prod_name}</a>
    price:{$product.prod_price}
    counter:{$product.prod_counter}
  {/foreach}
</div>
As shown above, the $op variable can be used as the key of the flow control. The system shows different web pages by composing different sub web pages in the main part according to $op. Now the flow stops at index.html again with new contents where allows user to trigger a new action again.

Friday, September 7, 2018

Reset AUTO_INCREMENT in MySQL

Reset AUTO_INCREMENT in MySQL

When creating a new record in MySQL server with a primary key, the “id” field (the primary key) is set to be auto incremented. Meaning the value of the primary key (“id” field) starts from 1, and the value of the primary key of the next record is increased by 1, which is 2. MySQL server takes cares of it without user interference.

What if the records have been deleted, and the primary key has to be reset to 1?

We can reset the counter with:

ALTER TABLE tablename AUTO_INCREMENT = 1

The primary key is reset to 1.