<![CDATA[Gorilla3D Blog]]>en-usGorilla3D Blog RSS Builder<![CDATA[PHP & Firefox 3 AJAX Image Upload]]>
Here is a sample dump of using firefox3's getAsDataURL to push to php and using GD to process it into an image and then save to file.

  1.  
  2. /* Ajax Functions */
  3. function Ajax(url, options) {
  4. if (typeof XMLHttpRequest!='undefined') {var page = new XMLHttpRequest();}
  5. else if (window.createRequest) { var page = window.createRequest();}
  6. else if (window.ActiveXObject) { var page = new ActiveXObject('MSXML2.XMLHTTP.3.0');}
  7. else { alert('Ooops, we failed to process your request. Tell us your browser please!'); }
  8. if (page) {
  9. if (options.method == 'post') {
  10. page.open('POST', url, true);
  11. page.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded") }
  12. else {
  13. page.open('GET', url, true);
  14. }
  15. page.onreadystatechange = function() {
  16. if (page.readyState == 4 && page.status == 200) {
  17. if ('function' == typeof options.onComplete) options.onComplete(page.responseText);
  18. }
  19. }
  20. if (options.method == 'post') {
  21. page.send(options.data);
  22. } else {
  23. page.send(null);
  24. }
  25. } else {
  26. alert('There has been a problem processing your request');
  27. }
  28. }
  29. function writeImage() {
  30. var imgdata = $('imagefile').files.item(0).getAsDataURL();
  31. var imgsize = $('imagefile').files.item(0).fileSize;
  32. var imgname = $('imagefile').files.item(0).fileName;
  33. Ajax("post.image.php", {"method":"post", "data": {"data":imgdata, "size":imgsize, "name":imgname}, "onComplete": function(image) { alert('uploaded'); }});
  34. }
  35.  


  1.  
  2. <input type="file" id="imagefile" name="imagefile" onchange="writeImage()"/>
  3.  


  1.  
  2. <?php
  3. $uploadfile = 'temp.jpg';
  4. //-- Parse the data
  5. $img_str = $_POST['data'];
  6. $img_str = explode('base64,', $img_str);
  7. $img_str = $img_str[1];
  8. $img_str = base64_decode($img_str);
  9. //-- Create image from string
  10. $image = imagecreatefromstring($img_str);
  11. //-- Save to file
  12. imagejpeg($image, $uploadfile, 85);
  13. ?>
  14.  
]]>
<![CDATA[Modular C++ Web Server / Framework]]>
Bare-Bone sample library
  1.  
  2. #include <stdio.h>
  3. #include "HttpModule.h"
  4.  
  5. class hello : public HttpModule {
  6. public:
  7. static char *get() {
  8. char *temp = "Hello World from a c++ sample";
  9. return temp;
  10. }
  11. };
  12.  
  13. // the class factories
  14. extern "C" HttpModule* create() {
  15. return new hello;
  16. }
  17.  
  18. extern "C" void destroy(HttpModule* p) {
  19. delete p;
  20. }
  21.  

Compile the dynamic lib
  1.  
  2. # compile into a shared library
  3. g++ -fPIC -c hello.cpp
  4. g++ -shared -o libhello.so hello.o
  5. # Using g++ on intel mac
  6. # g++ -dynamiclib -o libhello.so hello.o
  7.  


How does one then use this library on the server, well... I'll eventually make a configuration file, but for now you ave to directly edit the webserver.
  1.  
  2. module_map http_modules [] = {
  3. {"/helloworld", "./libhello.so"}
  4. };
  5.  


That correlates to http://localhost/helloworld and outputs "Hello World from a c++ sample"]]>
<![CDATA[Gorilla Db - (Improved) MySQLi Wrapper]]>mysqli wrapper to handle binds better and easier to new people trying to use prepared statements. I've also added Non-Filtered binds, because I'll also be release my Table class to help with simple queries you always end up running.

Db is a connection manager, it will use the connection you first create throughout your application. You can continue to call Db:init() and as long as a connection has already been made, you can run queries. Best of all It has prepared statements thanks to Wrapping MySQLi. For documentation and download please visit Gorilla Labs

  1.  
  2. //-- Prepared Statements
  3. // Execute a query
  4. $db->prepare('SELECT * FROM blog_entries WHERE id=?')->bind(23)->query();
  5. // or
  6. $db->prepare(SELECT * FROM blog_entries WHERE id=?);
  7. $db->bind(23);
  8. $db->query();
  9. // you can also stack binds
  10. $db->prepare('SELECT * FROM blog_entries WHERE id=? and title=?')
  11. ->bind(23)->bind('Hello World')->query();
  12. $db->prepare('SELECT * FROM blog_entries WHERE id=? and title=?')
  13. ->bind(array(23,'Hello World'))->query();
  14. $entry = $db->fetchOne();
  15.  
  16. // you can do can use them all in the same parameter
  17. $db->prepare('SELECT * FROM events WHERE name LIKE ? OR name LIKE ? and location LIKE ?')
  18. ->bind('%My%', '%Event%', '%San%')
  19. ->query();
  20.  
  21. // you can do can use an array and if they have keys you can assign you ?'s to them
  22. $db->prepare('SELECT * FROM events WHERE name LIKE ?arg1 OR name LIKE ?arg2 and location LIKE ?')
  23. ->bind(array('arg2'=>'%Event%'), '%San%', array('arg1'=>'%My%'))
  24. ->query();
  25.  
  26. // a cleaner example notice they can be in any order but you probably shouldn't
  27. $db->prepare('SELECT * FROM events WHERE name LIKE ?arg1 OR name LIKE ?arg2 and location LIKE ?')
  28. ->bind(array('arg2'=>'%Event%', '%San%', 'arg1'=>'%My%'))
  29. ->query();
  30.  
  31. // and yes keys can be used multiple times
  32. $db->prepare('SELECT * FROM events WHERE name LIKE ?arg1 OR name LIKE ?arg1 and location LIKE ?')
  33. ->bind(array('%San%', 'arg1'=>'%My%'))
  34. ->query();
  35.  
]]>
<![CDATA[Wordpress Plugin Development: Not so bad?]]>
Wordpress's Front-end (What everyone else see) is crap. But its Back-end is not half bad. I get access to their editor, users and so on.

So later this week I'll post a really clean plugin so you can all agree with me :) ]]>
<![CDATA[Gorilla Db - MySQLi Wrapper]]>
Db is a connection manager, it will use the connection you first create throughout your application. You can continue to call Db:init() and as long as a connection has already been made, you can run queries. Best of all It has prepared statements thanks to Wrapping MySQLi. For documentation and download please visit Gorilla Labs

  1.  
  2. $db = Db::init('localhost', 'root', 'pass', 'clients');
  3.  
  4. //-- Prepared Statements
  5. $rows = $db->query('SELECT * FROM blog_entries WHERE pub_date < ?', array('2008-04-01'));
  6.  
  7. echo 'Number of result: ' . $db->count();
  8. echo '<br/>';
  9.  
  10. echo 'SQL executed: ' . $db->debug();
  11. echo '<br/>';
  12.  
  13. $rows = $db->fetchAll();
  14. /* Output:
  15.  * Number of result: 22
  16.  * SQL executed: SELECT * FROM blog_entries WHERE pub_date < '2008-04-01'
  17.  */
  18.  
]]>
<![CDATA[Zend_Pdf Extension: Gorilla_Pdf_Page & Gorilla_Pdf_Table]]>

At work there is a growing need to move into pdf creation, since we generate all of our invoices via HTML. Some clients need precision on form creation. PDF offers that but Zend_Pdf lib is very limited. So I implemented text-wrapper and table class/functions to help guide me. Its far from done, but a good start to blog about it.

download Gorilla_Pdf file

  1.  
  2. $pdf = new Zend_Pdf();
  3. $page = new Gorilla_Pdf_Page(Zend_Pdf_Page::SIZE_LETTER);
  4. $font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_COURIER);
  5.  
  6. //-- Header
  7. $page->setFont($font, 24);
  8. $page->drawMultilineText(array('Purchase Order'), 390, 48);
  9.  
  10. $page->setFont($font, 10);
  11. $page->setLineWidth(0.5);
  12. $page->drawMultilineText(array('Szzzzice', '9zzzze', 'Szzzzzzzzzzzz26', 'Phone 8555-888-5 Fax 855-4-5554'), 33, 61);
  13.  
  14. $page->drawInfoBox('Date', array('2/29/2008'), 420, 61, 75, 45); // Header Text, Body Text, X, Y, Width, Height
  15. $page->drawInfoBox('PO #', array('000032'), 495, 61, 75, 45);
  16.  
  17. $page->drawInfoBox('Vendor', array('EMC', '3464 Blaire Dr.', 'San Deigo, CA 92081'), 33, 130, 248, 109);
  18. $page->drawInfoBox('Ship To', array('Billy Bob', '453 Wonker Rd.', 'San Deigo, CA 92081'), 320, 130, 248, 109);
  19.  
  20. //-- Draw inventory items
  21. $table = new Gorilla_Pdf_Table($page, 33, 300); // $pdf_page, start x, start y
  22.  
  23. //-- Output the table header
  24. $row = new Gorilla_Pdf_Table_Row();
  25. $col = new Gorilla_Pdf_Table_Column();
  26. $col->setWidth(26)->setText('Qty');
  27. $row->addColumn($col);
  28. $col = new Gorilla_Pdf_Table_Column();
  29. $col->setWidth(93)->setText('Item');
  30. $row->addColumn($col);
  31. $col = new Gorilla_Pdf_Table_Column();
  32. $col->setWidth(183)->setText('Description');
  33. $row->addColumn($col);
  34. $col = new Gorilla_Pdf_Table_Column();
  35. $col->setWidth(93)->setText('Customer');
  36. $row->addColumn($col);
  37. $col = new Gorilla_Pdf_Table_Column();
  38. $col->setWidth(49)->setText('Rate');
  39. $row->addColumn($col);
  40. $col = new Gorilla_Pdf_Table_Column();
  41. $col->setWidth(65)->setText('Amount');
  42. $row->addColumn($col);
  43. $table->addRow($row);
  44.  
  45. //-- Output the inventory
  46. foreach(range(0, 15) as $i) {
  47. $row = new Gorilla_Pdf_Table_Row();
  48. $col = new Gorilla_Pdf_Table_Column();
  49. $col->setWidth(26)->setText(strval($i)); // Qty
  50. $row->addColumn($col);
  51. $col = new Gorilla_Pdf_Table_Column();
  52. $col->setWidth(93)->setText('MAY-ULEX')->setAlignment('center'); // Inventory Code
  53. $row->addColumn($col);
  54. $col = new Gorilla_Pdf_Table_Column();
  55. $col->setWidth(183)->setText('Freedom Task Chair- with Standard Gel Armrests with Matching Textile Cover'); // Inventory Description
  56. $row->addColumn($col);
  57. $col = new Gorilla_Pdf_Table_Column();
  58. $col->setWidth(93)->setText('Billy Bob'); //-- Customer
  59. $row->addColumn($col);
  60. $col = new Gorilla_Pdf_Table_Column();
  61. $col->setWidth(49)->setText('64.00'); // -- Each Price
  62. $row->addColumn($col);
  63. $col = new Gorilla_Pdf_Table_Column();
  64. $col->setWidth(65)->setText(number_format(64 * $i, 2))->setAlignment('right');
  65. $row->addColumn($col);
  66. $table->addRow($row);
  67. }
  68.  
  69. //-- Output the table footer
  70. $row = new Gorilla_Pdf_Table_Row();
  71. $col = new Gorilla_Pdf_Table_Column();
  72. $col->setWidth(468)->setText('Total')->setAlignment('right');
  73. $row->addColumn($col);
  74. $col = new Gorilla_Pdf_Table_Column();
  75. $col->setWidth(65)->setText(number_format(64 * 16, 2))->setAlignment('right');
  76. $row->addColumn($col);
  77. $table->addRow($row);
  78.  
  79. //-- Render the table to the pages/s
  80. $pages = $table->render();
  81.  
  82. //-- If the table overflows onto a new page, they are created
  83. $pdf->pages[] = $page;
  84. foreach($pages as $page) {
  85. $pdf->pages[] = $page;
  86. }
  87.  
  88. $filename = rand().'.pdf';
  89. header('Content-type: application/pdf');
  90. header("Cache-Control: no-cache, must-revalidate");
  91. header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  92. echo $pdf->render();
  93.  
]]>
<![CDATA[Html/Php Contact Form]]>



Source code:
contactus.zip

HD Videos:
Part 1 - download
Part 2 - download]]>
<![CDATA[Php Video: Finding out execution time]]>

Watch this screen casting at 1024x768:
-- Php Execution Time - Theora ~ 5 megabytes
-- Php Execution Time - Mp4 avi ~ 26 megabytes

Free Php Debugger:
http://www.xdebug.org/

]]>
<![CDATA[Faster & Smarter MySQL Random Row Selection]]> geoip.sql ~ 94k rows | 7.8 MB

Figure 1. Shows the typical random MySQL random row Selection. On my server I ran 1000 iterations coming to about 0.6 seconds average in response time. The script took over 10 mins to execute 1000 random rows. Thats is awful performance and mean that if your site has more then 1 queries per second your database would crawl to a halt.

Figure 1. ~ 0.6 seconds
  1. <?php
  2. //-- Mysql Database Config
  3. $db_host = 'localhost';
  4. $db_db = 'mysite';
  5. $db_user = 'root';
  6. $db_pass = '';
  7.  
  8. //-- Mysql Connection
  9. $db_link = mysql_connect($db_host, $db_user, $db_pass)
  10. or die('MySQL Connection Error:'.mysql_error());
  11. or die('MySQL Error: Cannot select table');
  12. //-- Fetch a random row
  13. $sql = "SELECT * FROM `csv` ORDER BY RAND() LIMIT 1";
  14. $result = mysql_query($sql) or die(mysql_error());
  15. $row = mysql_fetch_assoc($result);
  16. ?>


Figure 2. Shows an alternative method yields 1000 iterations coming to about 0.001 seconds average in response time. Meaning your database can now withstand 1000 queries per second.

Figure 2. ~ 0.001 seconds
  1. <?php
  2. //-- Mysql Database Config
  3. $db_host = 'localhost';
  4. $db_db = 'mysite';
  5. $db_user = 'root';
  6. $db_pass = '';
  7.  
  8. //-- Mysql Connection
  9. $db_link = mysql_connect($db_host, $db_user, $db_pass)
  10. or die('MySQL Connection Error:'.mysql_error());
  11. or die('MySQL Error: Cannot select table');
  12.  
  13. //-- Find the largest ID
  14. $sql = "SELECT * FROM `csv` ORDER BY `id` DESC LIMIT 1";
  15. $result = mysql_query($sql) or die(mysql_error());
  16. $row = mysql_fetch_assoc($result);
  17. //-- Fetch a random row
  18. $max = intval($row['id']);
  19. $sql = "SELECT * FROM `csv` WHERE `id` = ". rand(1, $max) ." LIMIT 1";
  20. $result = mysql_query($sql);
  21. $row = mysql_fetch_assoc($result);
  22. ?>


Now what if your database has large section of missing ids (They skip in range, i.e 1, 3, 7)? Well look at Figure 3. This is an example of just looping the random selection based on the same code as Figure 2. The performance on this will very as it could be the 1st result that yields a row or the 100th, none of the less it still a far better alternative result then using MySQL's built in RAND() function to fetch random rows.

Figure 3. ~ N/A
  1. <?php
  2. // Mysql Database Config
  3. $db_host = 'localhost';
  4. $db_db = 'mysite';
  5. $db_user = 'root';
  6. $db_pass = '';
  7.  
  8. // Mysql Connection
  9. $db_link = mysql_connect($db_host, $db_user, $db_pass)
  10. or die('MySQL Connection Error:'.mysql_error());
  11. or die('MySQL Error: Cannot select table');
  12.  
  13. //-- Find the largest ID
  14. $sql = "SELECT * FROM `csv` ORDER BY `id` DESC LIMIT 1";
  15. $result = mysql_query($sql) or die(mysql_error());
  16. $row = mysql_fetch_assoc($result);
  17. $max = intval($row['id']);
  18. $result = false;
  19. //-- Query a random row until we get a result
  20. while(!$result) {
  21. $sql = "SELECT * FROM `csv` WHERE `id` = ". rand(1, $max) ." LIMIT 1";
  22. $result = mysql_query($sql) or die(