• Home
  • About
  • Who Am I?
  •  

    PHP Code Cleaner and Indenter

    December 19th, 2007

    Online Code Cleaner Demo

    With six years of experience with PHP , I have been ‘blessed’ with working with code written by really lazy people , who just didn’t think it was important at all to indent their code or comment it or make the opening and ending curly braces align.

    And sometimes our favorite FTP clients would add God knows why those silly annoying empty lines and the code would keep getting bigger and bigger.

    And I am sure that I am not alone in my frustrations.

    That is why is am writing this script which will try to take care of all that.

    Basically it will try to achieve the following goals:

    • Indent your code with tabs.
    • Put a comment block at the start of class definitions or functions.
    • Provide you with the facility to align curly brackets.
    • Remove unwanted lines from the code.
    • Put some spacing in blocks for improved readability.
    • Replaces short open tags with proper <?php tags
    • If a PHP block contains only one line , it will put the whole block in one line to improve readability.

    Please provide your valuable feedback to improve this script. I will be soon releasing a full script which will clean the code in all PHP files in a directory. Stay tuned!

    Online Code Cleaner Demo



    Web based FTP Sync Tool written in PHP

    December 4th, 2007

    FTP Sync Jobs ScreenFTP Sync 0.9

    PURPOSE:
    To upload files which have changed to your production server , automating the task of comparing which files have changed. You simply create a FTP job
    in the script , run the job and it will upload the changed files for you.

    REQUIREMENTS:
    FTP functions are required for this script to work.
    PHP 4 Or 5
    MySQL 4+

    INSTALL:
    Open dbinc.php and put in the database connection variables in there. Once done run installer.php from your browser and you are all set to go.
    Its advised to remove installer.php once you have finished installation.

    SECURITY:
    It if advised that the admin creates users and allocates jobs to them. Also the admin should block access to the database and script files
    from general staff.

    INFO:
    We made this script for our internal use , thought it might be useful for some of you out there. It was a tiring job to find which files needed to be uploaded
    to the main server after development on local server. Thus i created this script , where you can create jobs and upload folders and files which were changed.

    The decision to upload happens on 3 rules:

    1 : you can provide time and date in the job page , files which were created after that time will be uploaded.

    2 : you can ask the script to match the time against the server file , the script would calculate the time offset and calculate if the file has
    changed since last upload.

    3 : The script also keeps a log , if the file changed after last upload , it will upload the file.

    You can exclude the files you dont want to upload, for instance you wont want to upload and overwrite config.php or something like that. So you
    can create the skip list. The skip list is the path of the file from the source directory you have provided.

    For instance if you have a source directory called “/www/something/upload/” , and you dont want to upload the file “/www/something/upload/config.php”
    or the folder “/www/something/upload/users/images” then you would put in something like this:

    config.php
    users/images

    Remember no trailing slash for folders.

    You need to have writable permissions for the logs folder , also if you want to utlize the copy permissions feature you will need the BcMath library
    compiled with PHP.

    The admin can run any job , but if you want to have users which can run specific jobs only please utilize the users section , in which a user can
    run all jobs or only specific jobs.

    Same goes for the jobs , you can set an attribute to allow all users to run the job.

    This code has been tested on PHP 5 and PHP 4.4.

    You are free to modify the code as you please. The code is released in the public domain under the GPL license.

    Enjoy!



    PHP :: Serialize and Unserialize Alternative

    November 17th, 2007

    For quite sometime now I have been really annoyed by the unreliability of serialize and unserialize , when you would have a large string or some some special characters in there that wouldnt turn back into variables. So finally after not finding a decent alternative by someone else ( maybe I am only one suffering from the problem????? ) , I decided to write my own two functions.

    These two are working great for me , hope they serve some purpose to someone else. I am sure there is room for improvement here, please send in any suggestions or ideas to incorporate.

    Code (php)
    1.  
    2.         /// Usage
    3.         ////– first parameter is the var name , second is the var itself
    4.         $string = makeXML(’somevarname’ , $somevarname);
    5.  
    6.         ////— extractVars takes the above string as parameter ,
    7.         ////— and returns an arrray with variable name as key and variable itself
    8.         ///—  as value , i have used extract() to take all vars into code.
    9.         extract(extractVars($string));
    10.  
    11.  
    12.         function extractVars($xml , $name= , $type=){
    13.                 $reg="!<xmlvar name=\’(.*?)\’ type=’(.*?)’>(.*?)</xmlvar name=\’\\1\’>!s";
    14.                 preg_match_all($reg , $xml , $matches);
    15.  
    16.                 foreach($matches[1] as $index=>$key){
    17.                         $optname = $key;
    18.                         $opttype = $matches[2][$index];
    19.                         $optval = $matches[3][$index];
    20.  
    21.                         $optxpl = explode("::" , $optname);
    22.                         $optname = $optxpl[count($optxpl)-1];
    23.  
    24.                         if($opttype == ‘object’){
    25.                                 $bigarr[$optname] = (object)extractVars($optval , $optname , $opttype);
    26.                         }elseif($opttype==‘array’){
    27.                                 $bigarr[$optname] = extractVars($optval , $optname , $opttype);
    28.                         }else{
    29.                                 $bigarr[$optname] = $optval;
    30.                         }
    31.                 }
    32.  
    33.                 return $bigarr;
    34.         }
    35.  
    36.  
    37.  
    38.         function makeXML($name , $var="" , $parent = NULL ){
    39.                 if(!is_null($parent)) $parent = $parent."::";
    40.  
    41.                 if(is_object($var)){
    42.                         $xml .= "<xmlvar name=’$parent$name’ type=’object’>";
    43.                         foreach($var as $key=>$val){
    44.                                 $xml .= makeXML($key , $val , $parent.$name);
    45.                         }
    46.                         $xml .= "</xmlvar name=’$parent$name’>\r\n";
    47.                 }elseif(is_array($var)){
    48.                         $xml .= "<xmlvar name=’$parent$name’ type=’array’>";
    49.                         foreach($var as $key=>$val){
    50.                                 $xml .= $tab.makeXML($key , $val , $parent.$name);
    51.                         }
    52.                         $xml .= "</xmlvar name=’$parent$name’>\r\n";
    53.                 }elseif(is_bool($var)){
    54.                         $xml .= "<xmlvar name=’$parent$name’ type=’bool’>";
    55.                         $xml .= "$var";
    56.                         $xml .= "</xmlvar name=’$parent$name’>\r\n";
    57.                 }else{
    58.                         $xml .= "<xmlvar name=’$parent$name’ type=’string’>";
    59.                         $xml .= "$var";
    60.                         $xml .= "</xmlvar name=’$parent$name’>\r\n";
    61.                 }
    62.                 return $xml;
    63.         }
    64.  


    Affordable PHP 5 and MySQL 5 Hosting Available

    August 25th, 2007

    Decode IT has announced PHP 5 and MySQL 5 hosting.  After signup customers will be given a choice between version 4 and 5. The servers are dual core servers with high uptime and reliability. Small packages are ideal for Wordpress installations which can be done with clicks via the Fantastico control panel. All accounts contain the all time great CPanel account manager.

    Here is the overview….
    50 MB Hosting - $2.00 pm
    100 MB Hosting - $4.00 pm
    200 MB Hosting - $8.00 pm
    500 MB Hosting - $20.00 pm
    1000 MB Hosting - $35.00 pm

    You can find the details of the packages here.

    Enjoy!!



    Minor But Important Update to Wp Admin Switcher

    August 25th, 2007

    Thanks to a user , i have just tracked down a minor bug which could cause the plugin to breakdown with certain urls .. please download the zip from the download link provided on top right and update both .php files inside your /wp-content/plugins/wp-admin-switcher/ folder.



    Easily Switch Between Multiple Wordpress Admins - WP Admin Switcher V1

    August 1st, 2007

    WP Admin SwitcherJust finished my first plugin for wordpress called WP Admin Switcher. You can download this plugin here

    After you have installed this plugin you will be able to add information of multiple blogs you manage, the plugin will show you a drop down on top of all pages and let you switch between blogs. When you switch the plugin will attempt to show the same page of the other blogs administration panel. This plugin also works with free blogs from wordpress.com.

    The plugin requires CURL to be installed with PHP. Also please make sure to set the permission of the folder “tempfiles” to 777. Another point to keep in mind is that when you enter the URL of the administration panel in the WP Admin Switcher management page , please make sure you enter the correct URL. Some blogs are set to force www , so the page will keep redirecting to http://abc.com/wp-admin/ if you enter the URL like this http://www.abc.com/wp-admin/ . So make sure that enter the correct wp-admin URL.

    Have Fun!

    2nd Sept , 2007 : As someone pointed out there are several blogs out there that dont use mod_rewrite or permalinks , so thus plugin wont work out of the box for them , they need to create a mod_rewrite rule to point to the main index.php for wp-admin/virtual/ requests. If you dont have mod_rewrite available then this plugin is not going to work for you , maybe the next version will make it independent of mod_rewrite.


    24th Aug , 2007 : A bug was found which was leading to a breakdown in the plugins functionality , thanks to a user , this has been weeded out.


    5th Aug , 2007
    : Some adjustments were made to the script based on user feedback, if you are seeing messages which indicates that your request was blocked , please download the plugin again from the link above and see if it helps.



    Planet Source Code Winner!

    April 3rd, 2007

    Contest Winner
    Today i heard the unexpected news that my modest entry ( and I mean it) at plant source code won the contest. And they allowed me to show this on my site. Thought I would share it with the world. Though some of you might get cracking at me for it being CPU intensive or whatever , but as i said in the entry , it is just a pointer it is not a solution to be used for commercial heavy duty purposes.



    PHP : Attempting to Block Site Leechers/Crawlers

    March 18th, 2007

    Someone put forward a question on the forum regarding how to block leechers and I thought that my answer might make a good post as well.

    There is no fool proof way of going about it , cause there are ways in which a script can perfectly pretend to be a valid browser (CURL helps you do exactly that).you will have to put in use several different methods to fight them and reduce the illegal crawlers significantly.Other than the basic idea of banning the IP by getting it by REMOTE_ADDR and HTTP_X_FORWARDED_FOR here are some suggestions.

    Method 1:
    If there are too many requests from the same IP. Try to locate the ISP/Organization of the IP , like the GeoIP organization and ISP packages give you the database to lookup IP and see the owner. If IP belongs to a valid SE (and provided you want them to crawl) , let them go ahead. You can also do some effort to make a list of valid SE IPs which should override all crawler detections.

    Method 2:
    On the first request to the site , send a cookie , redirect and check if the cookie can be accessed, if not than redirect to a page asking the user to enable cookies.Generally scripts lack that ability.

    Method 3:
    Use javascript to set a cookie and then try to access it , if no cookie ask the user to enable javascript. Generic scripts wont be able to process javascript. Unless someone is writing code specifically for your site.

    Method 4:
    If too many requests show a captcha image which is not so straight forward. If no valid input atleast block that IP from going ahead. Even if alot of users are on that IP , you can show them a captcha again and validate that session_id to browse your site ,even if the IP is the same , a little nuisance but worth it if you have a severe problem.

    Method 5:
    Always check to see that a user agent header is sent , simple scripts written by newbies (and there are many) forget to send that.

    Method 6:
    After first entry , each request should contain a HTTP_REFERER logically , so check that too. Newbies forget to send that too.

    Method 7:
    If the same IP is generating different session_ids , you have a crawler on your hand.

    Ok thats all i can think of right now , some of the above might not make sense to some but if all of them are used effectively in combination with each other you got a great crawl blocker system on your hand. I would appreciate if people can suggest other methods as well.



    Latest CURL Issues with PHP (apache segmentation faults)

    March 1st, 2007

    Last couple of days i came across issues with CURL 7.15.3 , PHP 4.4.5 and Apache.

    There was this code i had to work on which was written by someone else , the guy was reusing the CURL handle more than one time and i was like …. eh? BUT interesting that code was working a few days ago , somehow during an update to apache etc that code stopped working. And the strangest behaviour was observed. Just imagine my surprise when a function wasnt returning control to the main script. Then i decided to check apache error logs and there it was … segmentation fault , with details

    glibc detected *** double free or corruption

    Now here is what was happening , a curl handle was generated , some post data was sent and then again that handle was used to send some more post data for a different page. The first request went through , but the second one errored out. Now ideally the handle shouldnt be reused in the first place. But earlier for some reason it was working fine and has been working great for a while.

    Now if you experiencing anything similar .. just stop reusing the handle , create a new one for every request and use that. Thats the way it should be done and thats the way you should do it. For instance the CURL wrapper class i have provided here does the same , it always creates a new handle , everything based on that class hasnt ever broken down. So watch out how you use your curl handles!



    PHP : CURL Insight and a PHP Alternative Example

    February 26th, 2007

    CURL has become increasingly popular over the past few years specially because of the fact that the web is becoming an active entity rather than a passive one , as it was in the yester years. CURL is a wonderful tool to communicate with other websites. CURL is also widely used in those “auto comment submit” type scripts. It makes the life of PHP developers easy. Alot of developers just consider it as a magic tool where as its nothing more than a way to format the request headers and play around with the response headers. Lets take a brief look at the insides of some of the CURL functions and what it really does. This article will be useful for situations where the curl library is not installed on the server.

    $ch = curl_init();
    Create the curl handle for use later.

    curl_setopt($ch, CURLOPT_URL,”http://www.abc.com/hello.php”);
    Tell curl the url you want to process.

    curl_setopt ($ch, CURLOPT_HEADER, true);
    Tell curl if it needs to return the response header as well along with the data.

    curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);

    Tell curl if it should oblige with the “Location:xyz.php” type response header command.

    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    This is the connection timeout limit.

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    Tell curl if it should return the data or not.

    curl_setopt($ch, CURLOPT_USERAGENT, “Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.1)”);
    Put the user agent type in the request header. This identifies what type of browser is requesting the page

    curl_setopt($ch, CURLOPT_REFERER, “http://www.google.com”);
    Put the referer url in the request header.Referer carries the page url where the user clicked on a link to request this page.

    curl_setopt($ch, CURLOPT_COOKIEJAR, “cookies.txt”);
    Provide the file name where curl will store the cookies sent by the web server in response headers.

    curl_setopt($ch, CURLOPT_COOKIEFILE, “cookies.txt”);
    Provide the file name where cookies are stored , and curl will send the cookies in there in the request headers.

    curl_setopt($ch, CURLOPT_POSTFIELDS, array(’username’=>’abc’ , ‘pass’=>’xyz’));
    Provide the post data if any as array , curl will put it in the request headers.

    curl_setopt($ch, CURLOPT_PROXY, “11.11.11.11:8080″ );
    Tell curl if it should send the request via a proxy , provide the ip and port.

    curl_setopt($ch, CURLOPT_PROXYUSERPWD,”user:pass”);
    If the above proxy requires authentication , provise the username and password here.

    $data = curl_exec($ch);
    Execute curl with all the above options and put the data in the $data variable.

    curl_close ($ch);
    Close the connection

    Now lets try to make some code which attempts to do the above with PHP.Please note that i am not trying ot create a full fledge CURL alternative here , i am just showing by example that it can be done easily with PHP , all you need to do is have some experience with headers. This is a not a perfect example script , so feel free to experiment around with it to get desired results.

    You can download the below code if my visual presentation skills with wordpress dont strike you as too good :) - Download the PHP CURL Alternative Example

    Code (php)
    1. <?
    2. $proxyip = "abc.com" ;
    3. $proxyport = "8080";
    4. $proxyuser= "proxy";
    5. $proxypass = "pass";
    6. $urltoprocess = "http://www.xyz.com/testit.php";
    7. $cookiefile = "cookies.txt"; // file must be set to be writable
    8. $referer = "http://www.google.com";
    9. $useragent = "Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.1)";
    10. $returntransfer = true; // — show return data
    11. $showresheader = true; // –show response header
    12. $shoreqheader  = true; // –show request header
    13. $parseurl = parse_url($urltoprocess);
    14. /////////////////
    15. //— make the post data string here
    16. $poststr = "";
    17. $postdata = array(‘username’=>‘abc’ , ‘pass’=>‘xyz’);
    18. foreach($postdata as $fldname => $fldval){
    19. $poststr .= "$fldname=".urlencode($fldval)."&";
    20. }
    21. /////////////////
    22. $contentlen = strlen($poststr);
    23. //– make the request header below
    24. //— check if proxy is to be used
    25. if($proxyip && $proxyport){
    26. $requestheader = "POST  $urltoprocess HTTP/1.1rn";
    27. $requestheader .= "Host: $proxyiprn";
    28. /////////////////
    29. if($proxyuser && $proxypass){
    30. $requestheader .= "Proxy-Authorization: Basic ".base64_encode("$proxyuser:$proxypass")."rn";
    31. }
    32. }else{
    33. $requestheader = "POST  $parseurl[path] HTTP/1.1rn";
    34. $requestheader .= "Host: $parseurl[host]rn";
    35. }
    36. //////////////////
    37. if($referer) $requestheader .= "Referer: http://www.google.comrn";
    38. if($useragent) $requestheader .= "User-Agent: $useragentrn";
    39. /////////////////
    40. //–add cookies to request header if cookies are to be used
    41. if($cookiefile){
    42. $allcookies = implode("" , file($cookiefile));
    43. if($allcookies){
    44. $requestheader .= "Cookie: $allcookiesrn";
    45. }
    46. }
    47. //////////////
    48. //–add post data to request header if any
    49. if($poststr){
    50. $requestheader .= "Content-Type: application/x-www-form-urlencodedrn";
    51. $requestheader .= "Content-Length: $contentlenrn";
    52. $requestheader .= "rn";
    53. $requestheader .= $poststr;
    54. }
    55. //////////////
    56. if($showreqheader){
    57. echo "<pre>";
    58. echo $requestheader;
    59. echo "</pre>";
    60. }
    61. /////////////////
    62. if($proxyip && $proxyport){
    63. $fp = fsockopen($proxyip , $proxyport , $errno , $errstr , 10);
    64. }else{
    65. if(!$parseurl[port]){
    66. if($parseurl[scheme] == "http") $parseurl[port] = 80;
    67. if($parseurl[scheme] == "https") $parseurl[port] = 443;
    68. }
    69. $fp = fsockopen($parseurl[host] , $parseurl[port] , $errno , $errstr , 10);
    70. }
    71. /////////////////
    72. /////////////////
    73. if(!$fp){
    74. echo "$errno : $errstr <br>";
    75. }
    76. /////////////////
    77. /////////////////
    78. fputs($fp , $requestheader);
    79. while(!feof($fp)){
    80. $raw .=fgets($fp , 1024);
    81. }
    82. fclose($fp);
    83. /////////////////
    84. /////////////////
    85. $setcookies = "";
    86. if($raw){
    87. $expl = preg_split("/(rn){2,2}/", $raw, 2) ;
    88. $header = $expl[0];
    89. $data = $expl[1];
    90. /////////////////
    91. /////////////////
    92. if($cookiefile){
    93. $headlines = explode("rn" , $header);
    94. foreach($headlines as $headline){
    95. if(substr_count($headline , "Set-Cookie")){
    96. $setcookies .= trim(str_replace("Set-Cookie: " , "" , $headline))."; ";
    97. }
    98. }
    99. }
    100. }
    101. /////////////////
    102. /////////////////
    103. if($setcookies){
    104. $fp = fopen($cookiefile , "w");
    105. fwrite($fp , $setcookies);
    106. fclose($fp);
    107. }
    108. /////////////////
    109. /////////////////
    110. if(!$returntransfer){
    111. $data = "";
    112. }
    113. /////////////////
    114. /////////////////
    115. if($showresheader){
    116. $data = $header."rnrn".$data;
    117. }
    118. /////////////////
    119. /////////////////
    120. echo $data;
    121. /////////////////
    122. ?>