Archive for the ‘PHP’ Category
LAMPs for the Mac
LAMP the ubiquitous acronym for Linux, Apache, MySQL, and PHP, Python, or Perl has a couple cousins. They are OPAL (Oracle’s stack on Linux, and MAMP (Mac OS X, Apache, MySQL, and PHP et cetera). Perhaps another acronym on the horizon is: OPAM (Oracle, PHP, Apache, and Mac OS X). OPAM is a guess on my part. Nobody knows what Oracle’s marketing department may choose. Regardless of the acronym for it, Oracle has published instructions for configuring an Oracle/PHP stack on Mac OS X.
I generally configure the OPAL stack with Zend Core for Oracle and the Oracle database on a virtual machine running Windows XP, Windows Vista, Ubuntu, or Red Hat Linux. If you follow my posts I prefer VMWare Fusion over Parallels. The MAMP stack I use is open source and provided by Living E. It follows the pattern of Mac OS X installations, which differs from the recent posting from Oracle. It’s easy to install, as you tell from the documentation. MAMP installs PHP 5.2.6 as the current release.
It’s a great choice when you incorporate the open source Sequel Pro tool. Isn’t it ashame that Sequel Pro doesn’t work natively with Oracle. If I find some time this summer, it might make a great project to extend it to Oracle. The interface to Sequel Pro looks like this:
When you create a connection, you should know the typical values. The database value can be left blank when connecting as the superuser root
:
Host: localhost User: root Password: root Database: Socket: /Applications/MAMP/tmp/mysql/mysql.sock Port: 3306 |
Here’s the connection dialog where you’ll enter the values:
Have fun playing with the MAMP stack.
No easy import into Excel 2008 for Mac
I thought it would be nice to walk through the Excel 2008 configuration steps to query Oracle. I was quite surprised when navigating the path, this error dialog was thrown:
When you navigate to the Microsoft web site, you’ll find that you have a choice of an ODBC driver from Open Link or Actual Technologies. You might think that Oracle would have their own ODBC driver that you can use without paying for a 3rd party solution. Unfortunately, there isn’t one. The most recent kits are missing the libsqora.so
shared library. The only ones that I could find are for the Mac OS X Tiger edition.
I may have missed something but you’ll find the Oracle documentation here. Feel free to comment with a solution. My solution is to use Code Weaver’s CrossOver Mac, and Microsoft Office 2007. How I regret the money wasted on Microsoft Office 2008.
A quick note, addendum, it looks like Actual Technologies is the best. Unfortunately, they charge for one copy for Oracle and another for MySQL and Postgre. What a discouraging note, but I may bite the bullet on the $60 bucks for both. I’ll defer the MySQL and Postgre until they release their 2.9 version. Don’t forget to also download Microsoft’s Query tool.
Migration was straightforward but …
I attempted to have a forward from the old WordPress.com site. That was a painful mistake! It took down both blogs with a circular referencing that was humorous I suppose. The DNS entries appear to all be corrected and forwarding straightened out. I apologize for any inconvenience.
As I update or expand entries, I’m entering a note in the old blog posts. I think the code segments are much improved, you can find SQL, PL/SQL, PHP, and Java examples in the following blog entries that are now perfect for cutting and pasting. Also, as noted the iPhone view is GREAT!
1. SQL example
2. PL/SQL example
3. PHP example
4. Java example
5. Shell example, DOS and Bash
Migrating wasn’t too hard, and here we are …
A number of friends wanted me to do things that weren’t possible while keeping my blog on WordPress.com’s web site. Things like code formatting, downloads for software, et cetera …
You can find the new blog at: http://blog.mclaughlinsoftware.com
So, I’ve migrated it to my own domain. I’m in the process of configuring the rest of the domain. I’ll update you through the blog as I complete the process.
I’ve got grand plans (lets hope there’s time). For example, I’m planning to migrate and update the TechTinker.com domain too. I’ll plan tutorials on Java, PL/SQL, and PHP initially as well as administration tips, techniques and walk through steps for my favorite platforms. As time allows, I’ve got some stuff comparing SQL across platforms – much beyond the trivial Oracle’s SPOOL
is MySQL’s tee
(not herbal tea).
While my perspective may change over time, I’m quite fond of Mac OS X, Ubuntu, and Red Hat. I won’t exclude Microsoft because we must live with it, but isn’t CrossOver sweet! I’d actually tried to get Oracle to run through it. I may yet, I’m still playing with it.
I’m trilled that Chris Jones and Justin Kestelyn got me blogg’n. I’ve always wanted to contribute more but the forums have mavens with much more time than I have to answer questions. The blog lets me share ideas and concepts as they travel with me on a daily basis.
Stats on the blog pages may not migrate but if time allows maybe I’ll write a plugin if I can’t find one. Generally, I don’t think anybody cares about the stats. It’s the information to solve problems, and I hope that’s what you find useful in my blog.
By the way, it wasn’t just the ability to have my blog pages look cool on my iPhone that drove the change, but it does look nice!!!
Adapter or not adapter that’s the question
The Adapter pattern in Object-Oriented OO programming is missing when it comes to how you can read, pass, and manage a PL/SQL system reference cursor. At least, it’s missing for PL/SQL native development. It is available through the OCI but only as a multiple dimensional array of strings.
Here’s an illustration of the Adapter Pattern (courtesy of the Design Patterns book by Gamma, Helm, Johnson, and Vlissides):
There are a few ways to handle reference cursor in PL/SQL. I’ve updated the earlier blog to more completely cover the options. In all cases within a PL/SQL environment, you must know the target type of the PL/SQL record structure. The target for converting a PL/SQL reference cursor is a a PL/SQL record structure.
You can assign a PL/SQL record structure through a PIPELINED table function to an aggregate table, which can be read by SQL. The following query lets you read an aggregate table back into a PL/SQL structure but begs the question of why you’d want to do that. The actual query by itself is in the updated blog entry linked above.
BEGIN FOR i IN (SELECT * FROM TABLE(use_of_input_cursor(weakly_typed_cursor('Harry')))) LOOP DBMS_OUTPUT.put_line('Item Title ['||i.item_title||']'); IF i.item_subtitle IS NOT NULL THEN DBMS_OUTPUT.put_line('Item Subtitle ['||i.item_subtitle||']'); END IF; END LOOP; END; / |
The OCI8 driver lets you take the system reference cursor from a PL/SQL block and translate it to a multidimensional array of strings. The following (borrowed from my book on PHP programming with Oracle) demonstrates how to open a statement and a reference cursor, which lets you manage the OUT mode parameter (covered in this earlier post) variable of a PL/SQL reference cursor. Our thanks should go to the OCI team because they see the world of interactivity.
// Declare a PL/SQL execution command. $stmt = "BEGIN world_leaders.get_presidents(:term_start ,:term_end ,:country ,:return_cursor); END;"; // Strip special characters to avoid ORA-06550 and PLS-00103 errors. $stmt = strip_special_characters($stmt); // Parse a query through the connection. $s = oci_parse($c,$stmt); // Declare a return cursor for the connection. $rc = oci_new_cursor($c); // Bind PHP variables to the OCI input or in mode variables. oci_bind_by_name($s,':term_start',$t_start); oci_bind_by_name($s,':term_end',$t_end); oci_bind_by_name($s,':country',$country); // Bind PHP variables to the OCI output or in/out mode variable. oci_bind_by_name($s,':return_cursor',$rc,-1,OCI_B_CURSOR); // Execute the PL/SQL statement. oci_execute($s); // Access the returned cursor. oci_execute($rc); |
You can query the results of the reference cursor ($rc), like this:
// Print the table header with known labels. print '<table border="1" cellpadding="3" cellspacing="0">'; // Set dynamic labels control variable true. $label = true; // Read the contents of the reference cursor. while($row = oci_fetch_assoc($rc)) { // Declare header and data variables. $header = ""; $data = ""; // Read the reference cursor into a table. foreach ($row as $name => $column) { // Capture labels for the first row. if ($label) { $header .= '<td class="e">'.$name.'</td>'; $data .= '<td class="v">'.$column.'</td>'; } else $data .= '<td class=v>'.$column.'</td>'; } // Print the header row once. if ($label) { print '<tr>'.$header.'</tr>'; $label = !$label; } // Print the data rows. print '<tr>'.$data.'</tr>'; } // Print the HTML table close. print '</table>'; |
Moreover, it would be wonderful if Oracle let you implement a full Adapter pattern but there are constructive ways to work with what we’ve got now. You actually get a bit more through the JDBC implementation but that’s for another blog I guess. As to adapter or not adapter, it’s clearly not.
Setting up a printer in VMWare Windows instance
Sometimes there are products that run in Windows that don’t have a clone on the Mac, like Microsoft Visio. Working in the virtual machine is the solution but printing is tedious to setup when you’re using a NAT network model. The following instructions show you how to setup a networked printer inside a VMWare instance that uses NAT networking. You can also use it when configuring it in a bridged network configuration. It is more or less the ordinary way for the Windows XP platform.
I found that the standard printer in the virtual machine wouldn’t work. I tried it in both VMWare 1.x and 2.x but without any luck. It did work ineffectively in VMWare 2.x but it embedded characters in simple documents that shouldn’t be there. Finally, I pursued this course. It has the benefit of working like you’d expect! It lets you print your native Windows documents when you’ve configured the VMWare machine in NAT. The same steps work when you’re using a bridged networking. In a bridged network, you don’t have to share the printer on the Mac OS because it directly accesses it.
The first step requires that you share you printer setup on the Mac OS. You do that by launching System Preferences, then click on Sharing. In Sharing, you enable print sharing by chosing the network printer …
After you’ve enabled sharing on the Mac OS, you can take the following steps in Windows:
1. Click the Start button, then choose Printers and Faxes. You’ll get the following screen where you should click the link to Add a printer. It will launch the Add Print Wizard.
2. You should install the printer drivers if they’re not already installed before launching the Add Print Wizard. You click Next In the first screen.
3. The default radio button is for a locally attached printer. Click the network printer radio button before clicking the Next button.
4. Click the Next button because the default browses for a network connected printer.
5. You shuold see the Microsoft Windows Network, and the default workgroup. Click on the Workgroup to display the possible machine names. If your machine doesn’t show in the list, it’s most likely because your printer wasn’t known in when Windows XP was released. The solution here is to insert the HP disk when you’ve connected it to the virtual machine, and then you simply follow the prompts, as shown in this newer post.
6. Click the appropriate machine that represents the hosting Mac OS (your machine that’s running VMWare). After you click it, you’ll see the target printers that are available through the external Mac OS connectivity and sharing. Click the Next button to proceed.
7. The last activity triggers a warning error. It asks you to confirm that you can trust your Mac. Click the Yes button to proceed (it’s a boring message but click on it if you want to read it).
8. Choose the printer as a default printer by clicking the Yes button. You can choose the No button if you’ve got more than one network printer.
There are problems when you forget to install the hardware first, so make sure you get the hardware installed first.
Nice “how-to” install OPAL on Ubuntu 8 Server
I noticed that somebody posted instructions and some scripts to install the OPAL (Oracle, Perl/PHP, Apache, Linux) in the OTN forum. I haven’t had a chance to run though it yet. Thought I’d point you to it directly. If you want the forum, go here. He’d like feedback in the forum.
PHP code to read a PL/SQL reference cursor
The following demonstrates how to read a PL/SQL reference cursor in a PHP program. The reference cursor function is defined in the Pipelined Functions & PL/SQL Tables blog page. I’ve commented it to the hilt for those new to PHP.
The reference cursor maintains a separate connection to the database to access the reference cursor. You also use the oci_fetch_assoc()
function to get the data. That strip_special_characters()
function lets you format your call to the PL/SQL program and remove non-parsing line returns and tabs before running the oci_parse()
function.
<?php // Return successful attempt to connect to the database. if ($c = @oci_connect("plsql","plsql","orcl")) { // Declare input variables. (isset($_GET['table'])) ? $table = (int) $_GET['table'] : $table = 'ITEM'; (isset($_GET['column'])) ? $column = (int) $_GET['column'] : $column = 'ITEM_TYPE'; // Declare a PL/SQL execution command. $stmt = "BEGIN :return_cursor := get_common_cursor(:table,:column); END;"; // Strip special characters to avoid ORA-06550 and PLS-00103 errors. $stmt = strip_special_characters($stmt); // Parse a query through the connection. $s = oci_parse($c,$stmt); // Declare a return cursor for the connection. $rc = oci_new_cursor($c); // Bind PHP variables to the OCI input or in mode variables. oci_bind_by_name($s,':table',$table); oci_bind_by_name($s,':column',$column); // Bind PHP variables to the OCI output or in/out mode variable. oci_bind_by_name($s,':return_cursor',$rc,-1,OCI_B_CURSOR); // Execute the PL/SQL statement & reference cursor. oci_execute($s); oci_execute($rc); // Print the table header with known labels. print '<table border="1" cellpadding="3" cellspacing="0">'; // Set dynamic labels control variable true. $label = true; // Read the contents of the reference cursor. while($row = oci_fetch_assoc($rc)) { // Declare header and data variables. $header = ""; $data = ""; // Read the reference cursor into a table. foreach ($row as $name => $column) { // Capture labels for the first row. if ($label) { $header .= '<td class="e">'.$name.'</td>'; $data .= '<td class="v">'.$column.'</td>'; } else $data .= '<td class=v>'.$column.'</td>'; } // Print the header row once. if ($label) { print '<tr>'.$header.'</tr>'; $label = !$label; } // Print the data rows. print '<tr>'.$data.'</tr>'; } // Print the HTML table close. print '</table>'; // Disconnect from database. oci_close($c); } else { // Assign the OCI error and format double and single quotes. $errorMessage = oci_error(); print htmlentities($errorMessage['message'])."<br />"; } // Strip special characters, like carriage or line returns and tabs. function strip_special_characters($str) { $out = ""; for ($i = 0;$i < strlen($str);$i++) if ((ord($str[$i]) != 9) && (ord($str[$i]) != 10) && (ord($str[$i]) != 13)) $out .= $str[$i]; // Return character only strings. return $out; } ?> |