|
|
|
|
|
|
Powered byD's Bloggie
| Weblog Archive browse by category ... |
|
|
|
|
How to enable Gzip compression on output buffer - 12:59 pm
Browser , Coding , Guides , PHP - DaRen
I've been updating this site since last month. One of the things I added is able to serve gzip-encoded page. On top of that, my site is also able to serve gzip-encoded CSS and JS file  Just scroll to the bottom of every page and you'll notice a line that says something like "Gzip enabled , CSS compressed , JS compressed". This will give an indication whether they are enabled or not. In other words, this will make pages load faster as well as saving some tiny bandwidth.
I've written a how-to thing that gives you an idea how to achieve that with PHP using ob_gzhandler(). For this to work you'll need the appropriate version of PHP, zlib extension and web browser that supports compressed web page.
Link: [PHP] How to enable Gzip compression on output buffer
Next topic will be on how to shrink, compress and cache CSS/JS files. Those who're using heavy AJAX and CSS styling will benefit from this.
Last edited: Wed 2007-05-30 @ 15:58 , by DaRen 2 time(s)
IP2Country binary database maker - 2:48 pm
Now in PHP....
Coding , PHP - DaRen
Half way through the site updates with lots of new codes and I thought the below script might be useful to some people... so, here you go !
IP2Country binary database maker (PHP)
Note: It's now added to my dev list here, always check there for latest news.
The IP2Country binary database maker in PHP that I written is a port from the original Python script from L. Petersen in Weird Silence, or a direct link to the source code zip file (inside makedb.py file).
The binary database created by this script can be used for IP to country lookup. If you need the script on how to use the database, visit Weird Silence - IP to Country. They have several languages for the implementation (eg. C#, PHP, Python, C, Delphi).
// +----------------------------------------------------------------------+
// | IP2Country binary database maker |
// | Copyright (C) 2007 Darren (http://ahkuan.com/weblog/199.html) |
// | |
// | File : ip_csv2dat.php |
// | Started : Monday, May 7, 2005 |
// | Version : 1.0 |
// +----------------------------------------------------------------------+
// | |
// | This is a PHP port with little modification from original |
// | Python script coded by |
// | L. Petersen , visit http://weirdsilence.net/software/ip2c/ |
// | |
// | What this script does is it converts the CSV database from |
// | IP-to-Country and GeoIP into binary database for quicker lookup |
// | |
// | Websites: |
// | IP-to-Country http://ip-to-country.webhosting.info |
// | Maxmind: GeoIP http://www.maxmind.com/app/ip-location |
// | |
// | Download latest CSV database: |
// | http://ip-to-country.webhosting.info/downloads/ip-to-country.csv.zip |
// | http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip |
// | |
// | *NOTE* |
// | Let me know if there is anything wrong with the code, especially |
// | whether the formatting code used in PHP's pack() function is the |
// | same as the Python or not. I have no Python coding experience at |
// | all when I'm porting the original Python script to PHP... so only |
// | God knows what mistake I've made unless you tell me ;) |
// | |
// | Also, I'm happy to hear if you have any improvements/suggestions. |
// | Use the 'Contact me' link on my page to contact me. |
// | |
// +----------------------------------------------------------------------+
Download
- ip_csv2dat.rar - PHP Source code rarred (CSV database included) (748 KB)
- ip_csv2dat.zip - PHP Source code zipped (CSV database included) (1 MB)
*Edit 2007.5.9* Added zipped file source code for download
*Edit 2007.5.30* Added to my dev list.
Listing all pictures on a page using Javascript - 11:30 pm
Browser , Coding , Cool Stuff , Guides - DaRen
Found a cool trick to display (nearly) all pictures on the web page you currently browsing.
- Open your browser
- Visit the page by typing the address of the web page in the address bar and hit [ENTER]
- Once the page has finish loading, copy & paste the below code to the address bar and hit [ENTER]
[ Hide ] javascript:Ai7Mg6P='';for%20(i7M1bQz=0;i7M1bQz<document.images.length;i7M1bQz++){Ai7Mg6P+='<img%20src='+document.images[i7M1bQz].src+'><br>'};if(Ai7Mg6P!=''){document.write('<center>'+Ai7Mg6P+'</center>');void(document.close())}else{alert('No%20images!')}
Firefox has its own media browser if you need something like that.
PHP class constructor - 12:33 am
Bug , Coding , PHP , Security , Site Issue - DaRen
I was doing some code clean up for my site and I found something interesting about the constructor in PHP class.
[ Hide ] <?php class Site { var $_DB; var $_User; function Site() { $this->_DB = new DB(); $this->_User = new User_Authentication(); } function process() { // some database access is needed in this function $this->_DB->query(); } } class DB { // ... some class implementation goes here ... } class User_Authentication { var $_local_DB; function User_Authentication() { // We reference to DB object in $SITE if exists, // otherwise we'll instantiate a new copy of DB locally if (isset($GLOBALS['mysite']->_DB )) $this->_local_DB =& $GLOBALS['mysite']->_DB; else $this->_local_DB = new DB(); // A test if the global var $mysite exists or not at this point echo isset($GLOBALS['mysite']) ? 'Var $mysite is there' : 'The global var $mysite does not exist !'; } function process() { // some database access is needed in this function $this->_local_db->query(); } } // Let's run the test ... $mysite = new Site(); // this will be a global variable ?>
Finish digesting the code ? Let's focus on Line 10 & 11:
10. $this->_DB = new DB();
11. $this->_User = new User_Authentication();
... and line 34 - 37
34. if (isset($GLOBALS['mysite']->_DB))
35. $this->_local_DB =& $GLOBALS['mysite']->_DB;
36. else
37. $this->_local_DB = new DB();
So you would thought that the global var $mysite->_DB is created before the new User_Authentication class is called. As a result, when it comes to line 34, the statement will valid and thus statement on line 35 will be carried out.
But the truth is opposite. You run the script and the output will be The global var $mysite does not exist !.
Why? The key to the problem is on line 11
$this->_User = new User_Authentication();
Although $this->_DB is created after line 10, but that does not mean $mysite->_DB, or even $mysite is listed in PHP defined variable list at that time.
That's because everything happens inside the scope of Site class's constructor. Object are considered 'defined' or 'instantiated' once the script execution exits the class constructor.
That's a hidden surprise if you're not careful enough =O
PHP isset() - 7:40 pm
Bug , Coding , PHP - DaRen
In PHP, sometimes you'll need to do alot of variable assignment like
[ Hide ] <?php
// simple
$bar = isset($foo) ? $foo : '';
// complicated
$bar = isset($foo[$test['index']]) ? $foo[$test['index']] : '';
?>
So I came up with this function to ease my life...
[ Hide ] <?php
// Use this to standardize things..
function isset_empty(&$input)
{
return isset($input) ? $input : '';
}
?>
Things works fine at first. But later then I discovered that it's not working like what I expected when I pass a value inside an array to that function. See below:
[ Hide ] <?php
$bar = isset_empty($foo); // $foo is undefined at this point
echo $bar;
$foo = array(1 => 'World', 2 => 'Cup');
print_r($foo);
$bar = isset_empty($foo[10]);
print_r($foo);
// The outpust result
// <-- emptry string, expected
// Array ( [1] => World [2] => Cup )
// Array ( [1] => World [2] => Cup [10] => )
?>
It seems that index 10 with empty string is inserted to the $foo array after calling that function. It doesn't harm in some situation but it's a real disaster if you're using array to populate items or doing a count($foo) to check the array size. The results are affected !
So I have to replace all the statements that uses the function and go back to the old way
$bar = isset($foo[$test['index']]) ?$foo[$test['index']] : '';
Doh!
Simple PHP Blog - 6:38 pm
Coding , PHP , Website Intro - DaRen
Just found a PHP blog project in SourceForge - Simple PHP Blog. It doesn't require a database, uses flat text files, and looked nice. Runs on PHP 4.
Looks simple and nice to me, but flat text file eh ?? I'm not really a big fan of it... imagine writing extra coding to process text file and performance degradation when you're dealing with large scale entries.
I haven't test the whole thing. But , it's not bad for short term blogging by just looking at their page though. Simple PHP Blog got the basic features like leave comment, trackback, permalink, search function, RSS feed and etc.
I'll check their admin control panel later on and study their code when I got enough time.
Visit their SourceForge project page, or their web page.
New design approach - 2:54 am
Coding , PHP , Site Issue , Site Updates , Standards - DaRen
I'm updating my site again. I've been working on the core functions / classes. Yes, the CORE part... The major ones are like user authentication and database connection. I've unified all database access under one global variable, avoiding multiple DB connection objects created locally (class/function scope). The good thing about ? it saves memory and I can know how many SQL queries are made to construct a page. Scroll down to the very bottom and you can see how like "N queries made". Quite surprising though... some pages used like 35 SQL queries... o.O omg... gotna refine them later...
My current approach [ Hide ] -------site_management.php---------------
// The class of "everything", contains db connection
// and other authentication
class site_management
{
var $DB_OBJECT;
function site_management()
{
// Let's say MYSQL_DB is your class that contains
// all functions to access/manipulate the database
$this->DB_OBJECT = new MYSQL_DB();
}
}
-------foo.php--------------------
// Some class that requires access to database
class foo
{
// Internal database connection object
var $_db_object;
function foo()
{
// If global variable $SITE->DB_OBJECT exists, make reference
// to it otherwise instantiate a new copy locally
if (isset($GLOBALS['SITE']) && $GLOBALS['SITE']->DB_OBJECT)
$this->_db_object =& $GLOBALS['SITE']->DB_OBJECT;
else
$this->_db_object = new MYSQL_DB();
}
function bar()
{
// You need to perform sql query here
$this->_db_object->query($sql); // for example
// ...
}
}
------test.php-------------------
// The above two class is located in different files
// and below is also in a seperate script file
<?php
$SITE = new site_management();
$foo_obj = new foo();
$foo_obj->bar();
?>
My old way [ Hide ] -------foo.php--------------------
// Some class that requires access to database
class foo
{
// Internal database connection object
var $_db_object;
function foo()
{
// Instantiate a new copy locally
$this->_db_object = new MYSQL_DB();
}
}
Let me know what you think about this. You can also leave me a message here.
Read more about referencing global variable:
http://www.php.net/manual/en/language.references.whatdo.php
http://www.obdev.at/developers/articles/00002.html
In authentication part I removed ALL spaghetti-style-redirection when transfering a user through a login/logout. In short, no more hidden values inside <form> to track user, session is used instead. Clean code and it works! Hopefully things will work fine... even though I'm extremely carefully when touching the core part, because almost everything are built on top of it.
You should also have notice the "N visitor(s) online now" thing on the left navigation menu. Although most of the time there is only 1 visitor, me myself  Talking about the navigation menu, I'm adding options to show/hide the menu with javascript. See that red button with a 'X' ? That's what I'm talking about.
Others updates are misc and minor updates in template/admin control panel.
Last edited: Mon 2005-10-17 @ 19:01 , by DaRen 1 time(s)
PHP Passing by Reference - 3:07 pm
Bug , Coding , PHP - DaRen
PHP's function supports passing by reference. However, default values may ONLY be passed by reference starting from PHP >= 5. Default values in PHP functions are like:
[ Hide ] // function declaration with default value
function foo($bar = 'default value here'){ ... };
// function declaration with passing by reference
function foo(&$bar){ ... };
What pissed me off is that I'm using PHP 5 for my computer but the hosting server is using PHP4. I only realize that PHP 4 doesn't supports that after I uploaded all my files to the server. Example of default values passed by reference:
[ Hide ] // This won't work in PHP < 5
function foo(&$bar = 'default value here'){ ... };
Workaround :
Set allow_call_time_pass_reference to true in php.ini if you're using php >= 5 so that you won't get a bunch of warning messages filling your screen.
Trick to do default values passed by reference [ Hide ] <?
// function declaration
function foo($bar = 'default value here') { ... };
// function calling
foo(); // valid call
foo(&$var); // this, however is consider deprecated in PHP >= 5
?>
Base on the above code:
PHP < 5 complains:
Parse error: parse error, expecting ')' and later on by a fatal error and killing the script execution.
PHP >= 5 complains:
Warning: Call-time pass-by-reference has been deprecated - argument passed by value; If you would like to pass it by reference, modify the declaration of [runtime function name](). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file. However, future versions may not support this any longer.
PHP urldecode() - 8:20 pm
Coding , PHP , Security - DaRen
Don't use a urldecode on a $_GET variable !
Say you have a script:
script.php [ Hide ] <?php
// Don't do this !
$value = urldecode($_GET['something']);
?>
Exploit:
An attacker can make a query to that script script.php?something=%2527 [...]
The fact...
PHP "receives" this as %27, which your urldecode() will convert to ' (the singlequote). This may be CATASTROPHIC when injecting into SQL or some PHP functions relying on escaped quotes -- magic quotes rightly cannot detect this and will not protect you!
Eg. This exploit affects phpBB < 2.0.11
Solution:
Just an example of how you can make that more secure:
PHP Single Quote vs Doubel Quote - 7:24 pm
Coding , PHP - DaRen
What's the differences between a ' (single quote) and " (double quote) in PHP programming ? They act quite the same. However, for double quotes, PHP checks the contents for a variable to interpolate and escape characters like the \n newline. This makes your scripts SLOWER. It's doesn't really matters if you're writing a small script, but it will help PHP parse faster in a larger script.
Consider the following:
[ Hide ] $name = 'Darren'; // This one's better
$name = "Darren";
That doesn't mean that double quotes are useless. It helps on readability in some situations:
[ Hide ] echo '<a href="' . $url . '">' . $text . '</a>';
echo "<a href=\"$url\">$text</a>";
// You cannot do a \n with single quote
echo "\nThis is a new line\n";
Using ' or " ? You should know which to use next time.
|
|
|
|
|