Sunday, May 29, 2011
PayPal – Authorize.net – Google Checkout
For e-commerce website: PayPal – Authorize.net – Google Checkout
Thursday, May 26, 2011
PHP class to do paging
This code can be easily ported to other languages. Note that the database used here is MSSQL, it has a paging function starting from version 2005 [1][2]. In MySQL, this can be achieved using 'Limit'.
On server side, the web service function (in C#) looks like this:
[1] Pagination in SQL Server
[2] retrieve specific range of rows in a SQL Server table
<html>
<head><title>Test</title></head>
<body>
<h1>Test Paging</h1>
<?php
// General variables for navBar.
$paging = new PagingClass( getService('getDataCount', array()), $_REQUEST['pg'] );
// Get data according to range.
$data = getService('getData', array('RangeStart' => $paging->getStart(), 'RangeEnd' => $paging->getEnd()));
// Output navBar and data.
print $paging->writeNavBar();
print Service2Table($data);
print $paging->writeNavBar();
?>
<?php
//
// @Author: HomeTom
// @Date: 5/26/2011
//
class PagingClass {
private $pageSize;
private $pageButtonCount;
private $totalCount;
private $pageCount;
private $currentPage;
private $BaseUrl;
//
// Parameters:
// $totalCount: Total number of rows/records.
// $curPage: Current page index (usually passed as request parameter).
// Preassumption: No parameter uses the name "pg", which is used for paging.
//
public function __construct($totalCount, $curPage) {
$this->pageSize = 3; // Default page size.
$this->pageButtonCount = 4; // Default number of paging buttons.
$this->totalCount = $totalCount;
$this->pageCount = ceil($totalCount / $this->pageSize);
$this->currentPage = $curPage;
if ($this->currentPage == "") { $this->currentPage = 1; }
else if ($this->currentPage < 0) { $this->currentPage = 0; }
else if ($this->currentPage >= $this->pageCount) { $this->currentPage = $this->pageCount - 1; }
// Base URL used by page links. Page parameter should be at the end. E.g. "index.php?pg="
$baseUrl = $_SERVER['PHP_SELF'] . "?" . $_SERVER['QUERY_STRING'];
if (preg_match("#pg=[0-9]*$#", $baseUrl) > 0) {
$this->BaseUrl = preg_replace("#pg=[0-9]*$#", "", $baseUrl) . "pg=";
} else if ( empty($_SERVER['QUERY_STRING']) ) {
$this->BaseUrl = $baseUrl . "pg=";
} else {
$this->BaseUrl = $baseUrl . "&pg=";
}
}
// Get start and end row/record number in current page.
public function getStart() { return $this->currentPage * $this->pageSize + 1; }
public function getEnd() { return (1 + $this->currentPage) * $this->pageSize; }
//
// Parameters:
// $PageCount: Total number of pages.
// $CurrentPageIndex: Current page index.
// $PageButtonCount: Number of page buttons to show on one page.
//
public function writeNavBar() {
$PageCount = $this->pageCount;
$CurrentPageIndex = $this->currentPage;
$PageButtonCount = $this->pageButtonCount;
$baseUrl = $this->BaseUrl; //"index.php?pg=";
$DEBUG = 0;
$lblNext = "Next";
$lblPrev = "Prev";
$lblFirst = "First";
$lblLast = "Last";
$s = "";
if ($DEBUG) {
print "pagecount: $PageCount, currentPageIndex: $CurrentPageIndex, ";
print "PageButtonCount: $PageButtonCount<br>";
}
$startPage = (floor(($CurrentPageIndex)/$PageButtonCount) * $PageButtonCount);
if ($DEBUG) print "startpage = $startPage<br>";
$tmp = $PageCount - $PageButtonCount;
if ($tmp > 0 && $tmp < $startPage) { $startPage = $tmp; }
// First.
if ($CurrentPageIndex == 0) { $s .= $lblFirst . " "; }
else { $s .= "<a href=\"" . $baseUrl . "0\">" . $lblFirst . "</a> "; }
// Prev.
if ($CurrentPageIndex == 0) { $s .= $lblPrev . " "; }
else
{
$j = $CurrentPageIndex - 1;
$s .= "<a href=\"" . $baseUrl . $j . "\">" . $lblPrev . "</a> ";
}
// ...
if ($startPage > 0) { $s .= "<a href=\"" . $baseUrl . ($startPage - 1) . "\">...</a> "; }
for ($i = 0; $i < $PageCount; $i ++) {
if ($i < $startPage || $i >= $startPage + $PageButtonCount) { continue; }
if ($i == $CurrentPageIndex) { $s .= " " . (1 + $i); }
else { $s .= " <a href='" . $baseUrl . $i . "'>". (1 + $i) . "</a>"; }
}
// ...
if ($startPage + $PageButtonCount <= $PageCount - 1) {
$j = $PageButtonCount + $startPage;
$s .= " <a href=\"" . $baseUrl . $j . "\">...</a> ";
}
// Next.
if ($CurrentPageIndex >= $PageCount - 1) { $s .= " " . $lblNext; }
else
{
$j = $CurrentPageIndex + 1;
$s .= " <a href=\"" . $baseUrl . $j . "\">" . $lblNext . "</a>";
}
// Last.
if ($CurrentPageIndex >= $PageCount - 1) { $s .= " " . $lblLast; }
else { $s .= " <a href=\"" . $baseUrl . ($PageCount - 1) . "\">" . $lblLast . "</a>"; }
return $s;
}
}
//
// This function retrieves a web service return result.
// http://www.php.net/manual/en/soapclient.soapcall.php
//
// Parameters:
// $func: Name of the web service function.
// $params: Array of parameters used by this function.
//
function getService($func, $params) {
try {
$url = "http://localhost/test/TestService.asmx?WSDL";
$client = new SoapClient($url);
$result = $client->$func($params);
//reset($result); // 'reset' sets the array pointer to the start of the array.
// 'each' gets the current key/value pair into a separate array.
list($key, $val) = each($result);
//print $key . ": " . $val . "<br>";
return $val;
} catch (Exception $e) {
die ("<br><font color='red'>getService() error: " . $e->getMessage() . "</font><br>");
}
}
//
// This function converts web service return result into a table.
//
// rows are delimited by '\n',
// cols are delimited by '\t'.
//
// explode() v.s. split():
// Biggest difference is explode() takes a delimiter to split by,
// while split() takes a regular expression. explode is faster.
//
function Service2Table($val) {
$row_delimiter = "\n";
$col_delimiter = "\t";
$DEBUG = 0;
$v = "";
$v_row = "";
$rows = explode($row_delimiter, $val);
$row_count = count($rows);
if ($DEBUG) print "<br>row count: " . $row_count . "<br>";
for ($i = 0; $i < $row_count; $i ++) {
$s = $rows[$i];
if ($s != "") {
if ($DEBUG) print "$i. $s<br>";
$cols = explode($col_delimiter, $s);
$col_count = count($cols);
$v_row = "";
for ($j = 0; $j < $col_count; $j ++) {
$v_row .= "<td>" . $cols[$j] . " </td>";
}
$v .= "<tr>$v_row</tr>";
}
}
$v = "<table border=1>$v</table>";
return $v;
}
?>
</body>
</html>
On server side, the web service function (in C#) looks like this:
[WebMethod]
public string getData(int RangeStart, int RangeEnd) {
string row_delimiter = "\n";
string col_delimiter = "\t";
string s = "";
string connStr = ConfigurationManager.ConnectionStrings["LocalDB"].ConnectionString;
SqlConnection conn = new SqlConnection(connStr);
conn.Open();
string sql = @"with TmpDataTable AS
(SELECT *, ROW_NUMBER() OVER (ORDER BY JobID) as 'RowNum' FROM DataTable)
SELECT * FROM TmpDataTable WHERE RowNum between " + RangeStart + " and " + RangeEnd;
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader sdr = cmd.ExecuteReader();
int fieldCount = sdr.VisibleFieldCount;
// get column names.
s = sdr.GetName(0);
for (int i = 1; i < fieldCount; i++)
{
s += col_delimiter + formatStr(sdr.GetName(i));
}
s += row_delimiter;
if (sdr.HasRows) {
// get column values.
while (sdr.Read()) {
s += sdr[0];
for (int i = 1; i < fieldCount; i++) {
s += col_delimiter + formatStr(sdr[i]);
}
s += row_delimiter;
}
}
conn.Close();
return s.Trim();
}
[1] Pagination in SQL Server
[2] retrieve specific range of rows in a SQL Server table
Tuesday, May 24, 2011
PHP upload size limit
Default PHP upload size limit is 2MB. That's too small.
A place to change this limit is in php.ini. Change "upload_max_filesize" and "post_max_size" bigger should save it [1][2]. Another place to increase this is in .htaccess [2]. If PHP SOAP client gives "Error Fetching http headers" warning, then you need to increase default_socket_timeout in php.ini to fix it [3].
[1] Howto optimize your PHP installation to handle large file uploads
[2] PHP Increase Upload File Size Limit
[3] PHP SOAP client giving "Error Fetching http headers"
A place to change this limit is in php.ini. Change "upload_max_filesize" and "post_max_size" bigger should save it [1][2]. Another place to increase this is in .htaccess [2]. If PHP SOAP client gives "Error Fetching http headers" warning, then you need to increase default_socket_timeout in php.ini to fix it [3].
[1] Howto optimize your PHP installation to handle large file uploads
[2] PHP Increase Upload File Size Limit
[3] PHP SOAP client giving "Error Fetching http headers"
Friday, May 20, 2011
Javascript PC simulator
Amazing for me: use Javascript to simulate a linux box in a browser:
http://bellard.org/jslinux/
http://bellard.org/jslinux/
Friday, May 6, 2011
More HTML5 and Javascript
- A list of javascript functions.
- HTML5 canvas - the basics
- Layering multiple canvases: good for avoiding over redrawing.
- Using Multiple HTML5 Canvases as Layers
- Layering Multiple Canvas Elements using JavaScript and EaselJS
- Understanding save() and restore() for the Canvas Context
- Canvas motion blur
- HTML/JavaScript - Select list - Add/Remove Options: DOM, Old school.
- innerHTML, innerText, textContent.
- Snippets: Howto Grey-Out The Screen
- jQuery: Grey out background and preview image as popup
- Javascript Create New Div HTML Element Dynamically
- Canvas tutorial - From Mozilla, a very good one.
- 10个让人眼花缭乱的HTML5和JavaScript效果
- 13 个强大的基于 HTML5 的 Web 应用
- 当设计师遭遇HTML5 - Good article
- HTML5 完胜 Flash 的 7 大特性
- HAKIM
- HTML5 Canvas Cheat Sheet
- Dive Into HTML5
- 10k Apart Contest
- Web audio in chrome
- Building better web apps with a new Chrome Beta
- 深入HTML5: HTML5 本地存储( Local Storage )的前世今生
Several HTML5 web app of my favorite:
- Keylight
- Blob
- FlowPower
- HTML5 canvas - the basics
- Layering multiple canvases: good for avoiding over redrawing.
- Using Multiple HTML5 Canvases as Layers
- Layering Multiple Canvas Elements using JavaScript and EaselJS
- Understanding save() and restore() for the Canvas Context
- Canvas motion blur
- HTML/JavaScript - Select list - Add/Remove Options: DOM, Old school.
- innerHTML, innerText, textContent.
- Snippets: Howto Grey-Out The Screen
- jQuery: Grey out background and preview image as popup
- Javascript Create New Div HTML Element Dynamically
- Canvas tutorial - From Mozilla, a very good one.
- 10个让人眼花缭乱的HTML5和JavaScript效果
- 13 个强大的基于 HTML5 的 Web 应用
- 当设计师遭遇HTML5 - Good article
- HTML5 完胜 Flash 的 7 大特性
- HAKIM
- HTML5 Canvas Cheat Sheet
- Dive Into HTML5
- 10k Apart Contest
- Web audio in chrome
- Building better web apps with a new Chrome Beta
- 深入HTML5: HTML5 本地存储( Local Storage )的前世今生
Several HTML5 web app of my favorite:
- Keylight
- Blob
- FlowPower
Sunday, May 1, 2011
Quine and Programming languages for fun
Quine is a program that prints itself. See wiki page on Quine. Here is a special Quine that prints a series of programs in 11 languages and eventually comes back to itself.
Here is an article BT雷人的程序语言(大全) about strange programming languages (made for fun in most cases). They are really funny. The end of this article gives these references:
- Esoteric_programming_languages
- Top 13 Most Absurd Programming Languages
- Befunge语言和文言文编程
- 疯狂的编程语言——ENGLISH,Chef Shakespeare
- DM’s Esoteric Programming Languages
- 十大另类程序语言(上)
- 十大另类程序语言(下)
Here is an article BT雷人的程序语言(大全) about strange programming languages (made for fun in most cases). They are really funny. The end of this article gives these references:
- Esoteric_programming_languages
- Top 13 Most Absurd Programming Languages
- Befunge语言和文言文编程
- 疯狂的编程语言——ENGLISH,Chef Shakespeare
- DM’s Esoteric Programming Languages
- 十大另类程序语言(上)
- 十大另类程序语言(下)
Subscribe to:
Posts (Atom)