Tag: php

  • Create Executable Images

    Introduction

    1. In this tutorial you will learn how to create executable image file
    2. Using the image you can perform any programmatic logic behind displaying an image
    3. The image created using PHP may not look unusual except the file extension will be .php
    4. We will overcome this drawback with Apache’s htaccess file with rewrite rules to masquerade our PHP file as image file

    Prerequisite

    1. Though you can use any image library like ImageMagick for this masquerading technique but we are planned to use GD image library
    2. GD is an open source graphics library
    3. GD library ‘s PHP official documentation link: GD Documentation

    Verification

    1. To check whether your server have installed PHP extension GD, execute the following command in your terminal/CLI php -i | grep 'GD'
    2. If you are uncomfortable with CLI you can create a PHP file in your webserver with calling the function phpinfo(); and load the page in browser and search for the GD
    3. If search not found the GD library then your server don’t have GD library

    GD Installation

    1. If GD library is not installed follow this section else skip it
    2. Installing for Debian based distro but you can follow the same command for red hat based distro by instead of using apt package manager use yum
    3. Package installation command: sudo apt install php-gd
    4. Once installed, GD library is activated and available in PHP CLI
    5. To make the GD module available as extension in Apache server execute the following command to restart with newly installed extensions are loaded
    6. Command: sudo systemctl restart apache2
    7. Verify once again as described in the Verification section to confirm GD installed

    Basic image on the fly

    1. In line 2 we call the GD function imagecreatetruecolor(640, 480) which create an image 640 px wide and 480 px height and assign this resource to a handle variable $handle
    2. In line 4 we call color allocating function imagecolorallocate($handle, 0, 255, 0)
    3. Where function imagecolorallocate accepts four parameters as follows handle, red, green, blue color’s value between 0 and 255
    4. In line 6 we call the function imagefilledrectangle(...) with first parameter as $handle an image resource, second parameter as x’s start coordinate integer value, third parameter as y’s start coordinate, fourth and fifth parameters are x’s and y’s end coordinate to form the rectangle, Last sixth parameter as color identifier value which is $green
    5. In line 9 we call the function header which is used to send a raw HTTP header to the called client side
    6. In header function call we pass the image type JPEG as content
    7. So the script will me considered as image and rendered as image
    8. In line 10 we call the function imagejpeg which have one mandatory parameter resource handle and two optional parameters $filename the path where dynamic image to be saved and $quality quality of the generated image by default it is 75 (minimum 0 and maximum 100)
    9. Finally on line 12 we call the another GD function imagedestroy destroy an image resource and free up the space
    10. Hurray! We created basic dynamic image which is in memory image i.e. it is in volatile layer RAM instead of persistent storage like HDD or SSD
    11. Next we use this in HTML file

    1. Use like the above image tag by replacing URL of src attribute to your server URL path
    2. Once embedded the image i.e. your PHP script in HTML file refresh the page in browser
    3. You will see the green colored big rectangle image

    Dynamic captcha image

    1. Let’s leverage what you learned in the previous section to create something more useful
    2. A random string generator which can be used as captcha validator
    3. The final script will display captcha string and some user’s client side details
    4. For this upgraded code we use most of the code in our basic image creation php file and use a helper function to generate random string

    1. In the above script most of logics between line 1 and 17 are explained in basic usage section
    2. In line 11 and 12 we call the GD function imagestring(...)
    3. The function requires six parameters they are $image the image resource’s handle, $font variable predefined font size between 1 and 5 or load registered fonts, $x x coordinate of upper left corner, $y y coordinate of upper left corner, $string the string to be written or rendered (here we pass our random string by calling the helper function rand_string or show render last accessed time in ATOM standard using date predefined constant), $color Color identifier generated by imagecolorallocate

    Random string generator helper function

    1. Let’s see helper function rand_string($length = 6)
    2. In line 23 we define the function rand_string with optional parameter $length with default value 6
    3. In line 26 we call the function range three times with arguments for start and end parameters are 0-9, a-z, A-Z
    4. range function return the array of elements from start to end here it fetches properly the sequence of integer, small and capital alphabet using ASCII code range
    5. Then three arrays are merged in to a single array using function array_merge and assigns it to the local variable $master_list
    6. In line 27 we call the array function shuffle by passing our $master_list array as parameter which will shuffle the array (Warning: this function uses new key so be cautious while using with associative array)
    7. In line 29 we call the function array_slice with first parameter as an array which is used as a source for the sliced array, the second parameter is offset from where the offset should be started we passed 0 so it will start from first element (Array’s index starts from zero), the third parameter is for the total element in the sliced array which is dynamically controlled by the optional parameter of our function
    8. So if we pass value 10 for the parameter $length then the default value of 6 is override into 10 and return 10 element from the shuffled array
    9. Which is assigned to the variable $sub_element
    10. In line 30 we make use of the variable $sub_element which is used as the argument for the function implode
    11. The implode function will convert our array into a string and assign it to the variable $to_string
    12. The implode function is little bizarre because it accepts first parameter as glue to join an array if only one parameter (array datatype) given to implode it will join all elements and form the string and reordering the argument is possible but it is deprecated so don’t call like this implode($array, $glue) though without glue is acceptable
    13. Finally in line 32 we return the random string generated by our helper function rand_string

    GD function use cases

    1. The use cases for GD is so many though this tutorial is for masquerading php script to image will share some use cases
    2. You can use it add dynamic watermark over the image
    3. You can use it to adjust the alpha channel or transparency of the image
    4. You can create random collage of the image
    5. To reduce the image quality (we used it to deliver low quality of the image to basic subscriber and high quality for premium user)
    6. To create image in various resolution (We used to save various resolution image in S3 using AWS elastic transcoder and lambda but same can be achieved for image using GD)
    7. As the image is dynamic you can control the access, expiry of the image
    8. Can be used for ethical hacking that’s why many email client won’t allow images download automatically if user need image they can take the risk and allow image to load
    9. Write copyright with dynamic year as watermark
    10. To track user activity many ad based company uses dynamic images for analytics

    Masquerading file extension from php to jpeg

    1. First create a file .htaccess in your tutorial project root directory
    2. Then add the given below snippet in your .htaccess file

    3. When you opened the PHP script URL as https://myhost.com/image.jpg if it throws not found error then your .htaccess is not called
    4. So you have to troubleshoot the configuration file which is in the path /etc/apache2/apache2.conf
    5. Open the file as a root user and find the following snippet in the configuration file
    6. Change the line AllowOverride None to AllowOverride All and save the file
    7. Once you reconfigured apache2.conf file restart the apache server by running the following command sudo systemctl restart apache2 to reflect the .htaccess
    8. Reload dynamic masqueraded image page (https://myhost.com/image.jpg)
    9. If still problem persists enable the rewrite module by executing the following command sudo a2enmod rewrite and restart the apache server once again

    .htaccess brief explanation

    1. First of all our .htaccess file is a basic one so don’t use this file as a production one but you use this snippet for any reference to change the file name or extension based on certain regular expression
    2. RewriteEngine On enables runtime rewrite engine
    3. RewriteBase / will be used as a relative path for our rewrite rule need more details here’s the link RewriteBase purpose
    4. RewriteRule ^image\.jpg image.php [L,QSA] is main rule which will rewrite URL from php extension to jpg likewise you can rename to anything like gif, bmp, etc., for more details RewriteRule purpose

    Sample dynamic image

    Conclusion

    1. Finally you learned the masquerading technique using Apache httpd server
    2. You learned about GD library and it’s use cases
    3. You learned how to created dynamic image on the fly
  • Inside the PHP

    Introduction

    1. Ever wonder what’s inside the PHP. How every language construct, function works.
    2. How optional parameters handled. Why certain functions behave weird and want know their inner working.
    3. That’s why I bring this tutorial to how easily navigate to the function declaration and understand it easily.
    4. Since PHP is opensource you can see all source code easily in github (clone of official git repository) but quickly finding the desired function in github is cumbersome but don’t worry we will find some alternative solution in this tutorial
    5. The PHP compiler/interpreter which is written in C and C++ which uses Lexical analyser, Yacc (Yet another compiler compiler), configurator to identify computer hardware and operating system finally virtual machine such as zend virtual machine shortly ZVM which runs our code

    Lets Explore Directory Structure and Pattern

    1. Most of the PHP source which is in C language looks very similar to PHP so understanding the code won’t be difficult.
    2. If the official documentation is more abstract you can get this procedure as a handy tool to understand the function very well.
    3. To explore the PHP source we are going to use Adam Harvey‘s PHP source browser. Lexer link: https://php-lxr.adamharvey.name/source/
    4. The PHP lexer’s home page have a search form in the left and source selection box in the right for simplification going to select php-7.3 in selection box.
    5. In selection box please double click the php-7.3 to goto the source listing.
    6. In the directory listing you will find some important directory like ext which contains core functions with the function’s name as sub-directories name, main comprises memory allocation code, directory scanning code, etc., Zend is the zend engine code which contains compiler, language features and VM (Virtual Machine).
    7. As you explored the ext and Zend directory it’s clear that in official documentation items which are found under “Language Reference” are related to zend directory and “Function Reference” are related to ext directory.
    8. Let’s we go into the Zend directory’s file zend_builtin_functions.c please click here which will redirect you to function lists in that c file.
    9. As you note down the code, you will see list of very familiar functions like zend_version, func_num_args, strlen, property_exists, class_exists, etc.,
    10. To dive deep into the internal code understanding process we chosen the string function explode.
    11. Here is the explode documentation link: explode()

    Explode() overview

    1. The function explode supports PHP 4, 5, 7 (Newbie Hint: There is no PHP 6 because core team planned to release PHP 6 long back with unicode support but not released. So to avoid confusion and marketing advantage PHP 7 is released after PHP 5).
    2. Explode function has two required parameters and one optional parameter totally three parameters.
    3. It return either boolean false or Array.
    4. From version 5.1.0 negative limit also supported.
    5. For more details about this function please review official document which is linked in last point of the previous section.
    6. Let’s we move to the internal working of this function.

    Search using LXR utility

    1. Go to the lexer home page. Link: https://php-lxr.adamharvey.name/source/
    2. In HTML form’s first field (Field Label: Full Search) type explode and click the button Search.
    3. It will show many matched results to narrow down we have to change the search term to "PHP_FUNCTION explode". Note: must enclose search term with double quotes.
    4. The search result lists the two files php_string.h and string.c
    5. The file php_string.h is similar to interface/ abstract class for a complete class. The file extension h denotes it’s a header file for main c file.
    6. Lets move on to our main objective file string.c by clicking the line number in the search result it will redirect us to the explode function’s declaration. Link: Line no: 1155.

    Explode() internal function call chain

    1. Explode function declaration starts with PHP_FUNCTION(explode) on line 1155.
    2. The declaration is enclosed inside between the markers {{{ and }}}. Note: Scroll up to see the marker.
    3. We can easily identify where the function declaration starts and ends using this markers.
    4. Here the PHP_FUNCTION is not a c inbuilt syntax it’s a C macro.
    5. The macro always start with #define
    6. So we will search in the lxr home page with search term "#define PHP_FUNCTION" or directly click here
    7. Once searched, the search list have the file name php.h in that click the line number 409
    8. In redirected source code page you will find that #define PHP_FUNCTION is points to other macro ZEND_FUNCTION
    9. Even though the hyperlink on ZEND_FUNCTION redirects you to the search form with filtered list it shows more records
    10. We will use alternative search term to filter more accurately for our need
    11. Once we used "#define ZEND_FUNCTION" as search term the utility page will list a file: zend_API.h in that list click the line number 64 or click here to redirect directly
    12. click here to redirect to lxr utility with search term
    13. The zend_API.h file’s line number 64 contains the following code
      #define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
    14. As you noted the 64th line have another two macros ZEND_NAMED_FUNCTION and ZEND_FN
    15. Lets we see inner function ZEND_FN
    16. In lxr search form add this search term "#define ZEND_FN" in full search field and click the search button or click here to go directly
    17. In result list you will find a file name zend_API.h with line no 61, please click the line number or click here to redirect
    18. Which have the following code #define ZEND_FN(name) zif_##name (in C the operator ## is for concatenation and it is called as token concatenation operator so it will return the concated string zif_explode)
    19. The ZEND_FN is passed as argument to the macro function ZEND_NAMED_FUNCTION
    20. In lxr search form add this search term "#define ZEND_NAMED_FUNCTION" in full search field and click the search button or click here to go directly
    21. It contains the following code #define ZEND_NAMED_FUNCTION(name) void ZEND_FASTCALL name(INTERNAL_FUNCTION_PARAMETERS)
    22. The function ZEND_FASTCALL will be interpreted as void ZEND_FASTCALL zif_explode(INTERNAL_FUNCTION_PARAMETERS)
    23. If we search for "#define ZEND_FASTCALL" it shows a list of search results in that click the first one’s line number or click here to go directly
    24. After redirected scroll up little and you will see the full block of C preprocessor conditional block
    25. This block is set of conditional call to choose the type of compiler as we know for windows, linux and other supported OS the compiler will be different
    26. Lets we arrange functions chain as a sequence block for easy mind map have a look on it
      PHP_FUNCTION(explode)ZEND_FUNCTION(explode)ZEND_NAMED_FUNCTION(ZEND_FN(explode))ZEND_NAMED_FUNCTION((zif_##explode))
    27. Readers thanks for your patience to follow the flow
    28. The reason to see the above steps before your eagerly expected internal flow of explode or name any core function is to understand that the PHP execute the core function in some better optimised way than the standard userland functions
    29. So our explode function starts the journey from PHP_FUNCTION(explode) to optimised call zif_explode

    Explode() function definition in C language

    1. As in previous section the explode code starts at the line number 1153 with the markup {{{ and ends at the line number 1192 with the markup }}}
    2. Line 1155 : is the macro call and that call itself has a separate section which is explained in the previous section
    3. The lines 11571159: are the C local variables and some of the variables are used for arguments we passed in explode function’s parameters
    4. The lines 11611166: are used to copy the runtime input parameters to the local variables
      1. Line 1161: is a macro call ZEND_PARSE_PARAMETERS_START(2, 3) this function is used to initiate the process of copying runtime value into the local variable which defined just above this macro call
      2. This function has two parameters the first one for number of mandatory parameters and the second one is total number of parameters
      3. Line 1162: is macro function Z_PARAM_STR(delim) which accepts string value
      4. This macro copy the delimiter string value passed as first parameter in the explode function to the local variable delim
      5. Line 1163: Z_PARAM_STR(str) copy the string value passed as second parameter in the explode function to the local variable str
      6. Line 1164: Z_PARAM_OPTIONAL is used indicate from here to end of parse parameter block all the variables are optional one
      7. Line 1165: Z_PARAM_LONG(limit) is a function used to copy the PHP’s int datatype value to the C’s long datatype variable
      8. explode function’s third parameter $limit which is optional whose value is copied to the C variable limit
      9. If not passed then ZEND_LONG_MAX macro’s constant will be set, it’s based on 32 bit or 64 bit system the value’s size may vary
      10. Line 1166: ZEND_PARSE_PARAMETERS_END(); denotes the end of the parameters parsing and copying to local C variable and this is end of this block, note in this block this line only ends with semicolon to denote the block’s completion
    5. The lines 11681171 is a block which check delim is a empty string by checking the length and throws error
      1. Line 1168: if (ZSTR_LEN(delim) == 0) uses the macro function ZSTR_LEN which counts the character in the string and returns it’s length which compares with integer 0
      2. If boolean comparison is true, then code execution move into the block else if false then it skips the block completely
      3. Line 1169: php_error_docref(NULL, E_WARNING, "Empty delimiter"); is a error throwing macro function which throw warning error
      4. The first parameter of function php_error_docref is char datatype with NULL as a value and the remaining two parameters are self explanatory
      5. Line 1170: is a macro which compare it to constant macro value 2 which is for zend false type IS_FALSE you can find it by going upto the beginning of this macro’s call by clicking and follow the hyperlink from RETURN_FALSE which redirects it to ZVAL_FALSE and go on
    6. Line 1173: array_init(return_value) is an array API function which initialize a hash table for an array, additional info: internally PHP array itself a hash map (If possible in future will put a tutorial on Array’s internal!)
    7. The lines 11751181 is a block which is used to free up zval when the source string which need to be explode but passed as empty string and execute return to return result from the PHP_FUNCTION macro function
      1. Line 1175: if (ZSTR_LEN(str) == 0) checks if the passed string (to explode) length is equal to zero
      2. Line 1176: if (limit >= 0) checks the optional third parameter of the explode function (in C it’s local variable is limit) is greater than or equal to zero
      3. If limit variable’s boolean comparison is true then calls the inner block
      4. Line 1177: ZVAL_EMPTY_STRING(&tmp); which empties the tmp zval
      5. Line 1178: zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp); first using Z_ARRVAL_P is used to fetching the value of array type and passed it to the function zend_hash_index_add_new which is hash table API wrapper around the function _zend_hash_index_add_or_update_i for reference document doxygen document
      6. 1180: is a simple return to return empty array
    8. The lines 11831190 is a decision logic block based on the limit value it will split the string from left to right upto the limit lastly it have the whole left out string in last index or right to left upto the limit and remaining string will be neglected and the final else part is to handle limit of 0 or 1 which return the complete string as an array with whole string in first index
      1. Line 1183: if (limit > 1) which is straightforward boolean logic which checks is local variable limit is greater than integer 1
      2. Line 1184: php_explode(delim, str, return_value, limit); is the PHPAPI macro call with all parameters easy to understand except the third one return_value which is zval* provided by the macro function PHP_FUNCTION
      3. Line 1185: else if (limit < 0) which is straightforward boolean logic which checks is local variable limit is lesser than integer 0 i.e. negative number
      4. Line 1186: php_explode_negative_limit(delim, str, return_value, limit); is the PHPAPI macro call with all parameters same as php_explode but this API is for negative limit
      5. Line 1187: is the last block of this if-else ladder
      6. Line 1188: ZVAL_STR_COPY(&tmp, str); is a macro which is used to copy the string in the local variable str to zval generic pointer type local variable tmp
      7. Line 1189: is similar to the point 7.5 of this section

    Conclusion

    1. Now you are ready to explore any PHP function easily by applying the same procedure we discussed
    2. You learned the directory structure of the PHP source
    3. You learned how to use lxr utility
    4. You learned how PHP_FUNCTION macro is working
  • Tombstone

    1. Tombstone is the dead code detection library for PHP
    2. In our real life most of the time we use only 20 percentage of any application frequently
    3. So using Tombstone library (GitHub link: scheb/tombstone) we will check how to remove zero times or rarely called functions
    4. As a result our codebase will get slimmer and healthier by removing unwanted functions
    5. Leaving dead code in project makes it much harder to find the bugs
    6. Using IDE’s find usage we can easily identify whether the function is called or not
    7. But if function a() called inside function b() which is called inside function c() and function c() is nowhere used it’s difficult to identify these kind of issues
    8. So for these kind of issue, dead code deduction library will be used as handy tool
    9. Tombstoning is a basic step by placing a marker code inside our code block where you think the code is dead
    10. Once you placed the marker code wait for a while and allow users to use your application
    11. After that you will get a log of all called functions so these called functions are still in use
    12. Hope you understand the theory part of how tombstoning process works
    13. Lets we see it in practical way by using the library scheb/tombstone
    14. First import vendor package scheb/tombstone in your codebase using composer
    15. Create the tombstone helper as like the given below gist if you have doubt please refer the sample github toy project linked at the last
    16. The class Tombstone helper has three main components public property $logPath to assign the log path, constructor which is used to add the stream handling for our log file and finally we created a public method tombstone() to do the tombstoning process
    17. We created helper and now we are going to use tombstone method in our code.
    18. Please refer the given below gist
    19. Here in class DeadCode we have two method called() and notCalled() with tombstone marker
    20. As you noted in our tombstone marker method we passed two arguments first one is marker created date and second one is who created the marker
    21. We call our DeadCode::called() method but not the DeadCode::notCalled() (don’t panic we didn’t print anything so the index.php page is remain blank)
    22. So after few times of execution of index page and when we see our log we found that DeadCode class method notCalled() wasn’t logged
    23. The log is appended in tombstones.log file you can easily parse what each line of log says: when the log was logged with tombstone date and who called in which file at which line number in which function and in which function it was invoked
    24. So the method DeadCode::notCalled() is the safe candidate to remove from our code because that method is called nowhere
    25. Please find the simple sample for dead code detection (GitHub link: deadcode detection)

  • PPT to PDF

    1. The above one line shell snippet in php script is used to convert the powerpoint file in to PDF file using libreoffice. The same command can be used for all the files which are able to open using libreoffice like doc, docx, odt, odp, etc., Shell command is enclosed in back tick symbol not single quotes. PHP by default execute command inside back tick as shell command alternatively you can use shell_exec
    2. Let’s we see each arguments and it’s description (this is an excerpt from official document) we passed to the shell command libreoffice
    3. --headless        Starts in “headless mode” which allows using the application without GUI. This special mode can be used when the application is controlled by external clients via the API.
    4. --invisible        Starts in invisible mode. Neither the start-up logo nor the initial program window will be visible. Application can be controlled, and documents and dialogs can be controlled and opened via the API. Using the parameter, the process can only be ended using the taskmanager (Windows) or the kill command (UNIX-like systems). It cannot be used in conjunction with –quickstart.
    5. --convert-to OutputFileExtension[:OutputFilterName] \ [--outdir output_dir] [--convert-images-to]        Batch convert files (implies –headless). If –outdir isn’t specified, then current working directory is used as output_dir. If –convert-images-to is given, its parameter is taken as the target filter format for *all* images written to the output format. If –convert-to is used more than once, the last value of OutputFileExtension [:OutputFilterName] is effective. If –outdir is used more than once, only its last value is effective. For example:
      --convert-to pdf *.odt
      --convert-to epub *.doc
      --convert-to pdf:writer_pdf_Export --outdir /home/user *.doc
      --convert-to "html:XHTML Writer File:UTF8" \
      --convert-images-to "jpg" *.doc
    6. Finally we pass shell command textual output to virtual device /dev/null using > symbol in linux based distros whatever it receives as input it will discard it. As a result there won’t be displaying of any message when you using this snippet inside your custom function or method.