Archive for the ‘Zend’ Category
Display Errors with Zend
Someone asked how to display errors in the HTML output when they test PHP scripts with the Zend Server CE. Here are the two screen shots that help you enable the display of error and warning messages in your HTML display.
- Click the Server Setup tab and then click the Error Handling and Logging choice.
- Click the On radio button for Display errors and then restart PHP at the bottom right corner.
Hope this helps people looking for the navigation.
Zend CE has a Worm?
After updating the AVGFree virus definitions, I was surprised to find that Zend CE (Community Edition) 4.0.6 had a reported worm in the JavaServer.exe
file. There was greater surprise when Zend CE 5.3.9 (5.6.0-SP1) also had the same reported worm.
This is the message identifying the worm (click on it to see a full size image), and you can read about this particular worm on the Mcafee site or the AVG threat labs site:
If you check AVGFree’s page, the actual infection isn’t a stated variant, but it appears the heuristics are a bit aggressive.
File Name: C:\Program Files (x86)\Zend\ZendServer\bin\JavaServer.exe Infection: Win32/DH.FF860061{00000000-00080000-00000000} |
Unless you have the full version of AVGFree or another security program to try and fix the file, you can only quarantine the file. Quarantine or removal disables Zend CE from working. It begs the question: “How does Zend release a core file with a worm?” or “Is AVGFree reporting a false positive?”
Update: AVGFree was providing a false positive. In addition to the checks by Zeev at Zend, I created a new test instance with Norton 360 and it likewise found no virus/worm in Zend’s JavaServer.exe
file. Hopefully the post will prevent others from spending more than a Google search to sort it out.
Since I use AVGFree on all my Windows 7 VM test instances, it seemed logical to illustrate how to work around this current false positive and annoying quarantining of the core JavaServer.exe
file from the Zend Server. There are two sets of tasks, the first requires removing the file from quarantine and the second eliminates future scans from quarantining the file again.
Remove the file from the Virus Vault
- Launch AVGFree and navigate to the History menu option and choose the Virus Vault option, as shown below.
- Click the Virus Vault option in the list of the History, which displays the following screen. Click the Infection row and then click the Restore button to remove the file from the virus vault.
- A confirmation dialog opens and you click the Yes button to proceed.
- The Infection row is gone When you’re returned to the History dialog. Click the Close button to complete this task.
Exclude the file from future scans
- Select the Tools menu option and choose the Advanced settings … option, as shown below.
- Click the Excluded files option in the list of the History, which displays the following screen. Click the Add button to select the file for exclusion. Click the Apply button to effect the change and the OK button to complete the change.
All I can say, one the AVGFree false positive was annoying and it’s dark at 3 a.m. and light the next day. 😉
Thanks to those who knew or surmised it was AVGFree’s heuristics and took the time to add a comment.
The ereg() function is gone
Alas, poor ereg()
I abused you well. PHP 5.3 has deprecated ereg()
and now we must move forward with preg_match()
. Along with that change, somebody asked me to show how to upload images to the file system as opposed to the database. Personally, I think they should be stored in the database.
With my bias toward databases, I threw in a virtual directory mapping in a MySQL database because it doesn’t natively support an Oracle equivalent BFILE
data type. You can see this older post how to use the DBA_DIRECTORIES
view in Oracle to mimic this behavior.
Naturally, MySQL is the preferred database of the person asking the question. You could also implement this exactly the same in Oracle but you really don’t want to do so. Using Oracle’s virtual directories has it’s own pre-built set of security features. They provide a more robust solution.
The code is presented as follows (setup for MySQL instructions):
- Create and seed the
DIRECTORY
table in MySQL:
-- Create a directory table. CREATE TABLE directory ( directory_id INT PRIMARY KEY AUTO_INCREMENT , virtual_name VARCHAR(30) , directory_name VARCHAR(60)); -- Seed the table with a virtual directory mapping. INSERT INTO directory VALUES ( NULL,'CMS_IMAGES','C:\\Data' ); |
- Create a
MySQLCredentials.inc
credentails file for inclusion in the PHP program:
1 2 3 4 5 6 7 | <?php // Connection variables. define('HOSTNAME',"localhost"); define('USERNAME',"student"); define('PASSWORD',"student"); define('DATABASE',"sampledb"); ?> |
- Create the PHP uploading program, named
MySQLFileUpload.php
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | <?php // Set database credentials. include_once("MySQLCredentials.inc"); // Declare input variables. $id = (isset($_POST['id'])) ? $_POST['id'] : 1021; // Upload a file to server in a mapped physical drive location. if (process_uploaded_file(map_virtual_directory($id))) print "Successfully Uploaded the file.<br />"; // Map a virtual directory to a physical directory. function map_virtual_directory($virtual) { // Return successful attempt to connect to the database. if (!$c = @mysqli_connect(HOSTNAME,USERNAME,PASSWORD,DATABASE)) { // Print user message. print "Sorry! The connection to the database failed. Please try again later."; // Return error message. print mysqli_error(); // Kill the resource. die(); } else { // Initialize a statement in the scope of the connection. $stmt = mysqli_stmt_init($c); // Declare a case insensitive dynamic SQL statement. $sql = "SELECT directory_name FROM directory WHERE virtual_name = UCASE(?)"; // Prepare the statement. if (mysqli_stmt_prepare($stmt,$sql)) { // Bind the input parameter to the prepared statement. mysqli_stmt_bind_param($stmt,'s',$virtual); // Execute the prepared statement. if (mysqli_stmt_execute($stmt)) { // Bind the result to a local variable. mysqli_stmt_bind_result($stmt,$directory); // FetchPrepare statement and link it to a connection. while (mysqli_stmt_fetch($stmt)) return $directory; } else // Return error message. print mysqli_error(); } else // Return error message. print mysqli_error(); // Disconnect from database. mysqli_close($c); } } // Manage file upload. function process_uploaded_file($directory) { /* Assume the application may allow a virtual directory with a trailing backslash or forward slash to be stored in the database, and manage both scenarios across Windows and Linux. */ if (preg_match(".Win32.",$_SERVER["SERVER_SOFTWARE"])) if (preg_match("/\b\\\/",$directory)); else if (preg_match("/\b\//",$directory)) { $directory = substr($directory,0,strlen($directory)-1); $directory = $directory."\\"; } else $directory = $directory."\\"; else if (preg_match("/\b\//",$directory)) $directory = substr($directory,0,strlen($directory)-1); else $directory = $directory."/"; // Check for, move uploaded file, and confirm processing. if (is_uploaded_file($_FILES['userfile']['tmp_name'])) { // Move temporary cache into a file directory with the uploaded file name. move_uploaded_file($_FILES['userfile']['tmp_name'],$directory.$_FILES['userfile']['name']); // Remove this from real code, it's here for example only. ;-) print "Uploaded [".$_FILES['userfile']['name']."] to".$directory."<br />"; // Return true to encapsulate the functional logic on success. return true; } else // Return false to encapsulate the functional logic on failure. return false; } ?> |
- Create a web page to test it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <html> <head> <title> UploadFileFormMySQL.htm </title> </head> <body> <form id="uploadForm" action="MySQLFileUpload.php" enctype="multipart/form-data" method="post"> <table border=0 cellpadding=0 cellspacing=0> <tr> <td width=125>Item Number</td> <td> <input id="id" name="id" type="text"> </td> </tr> <tr> <td width=125>Select File</td> <td> <input id="uploadfilename" name="userfile" type="file"> </td> </tr> <tr> <td width=125>Click Button to</td> <td><input type="submit" value="Upload File"></td> </tr> </table> </form> </body> </html> |
Hope this helps a few folks. I imagine that the prepared statement with bound variables may help a few folks because it’s not found (at writing) on the php.net
web site.
Windows 7 and Zend CE
Installed Zend Community Edition on Windows 7 64-bit. It worked easily. You just need to remember to install the JSDK 32-bit version for the Java Bridge. Clear notation about phpMyAdmin and MySQL being separate downloads has been added to the new Zend Community Edition Server (4.0.6), and it clearly does support Windows 7.
If you plan on installing MySQL and Oracle, I would recommend you install MySQL after you install Oracle and the Zend Community Server. However, it doesn’t matter because both ways work.
That completes my WAMP (Windows, Apache, MySQL, Perl, PHP, or Python) and OPAW (Oracle, Perl, PHP, or Python, Apache, Windows) installations. Actually, I’m not sure there is an OPAW acronym for a LAMP stack running Oracle on a Windows platform. OPAL is the acronym for a LAMP stack running an Oracle database, but I’ve never seen one before for Windows. Therefore, I created one.
My two cents worth …
I’d vote for clearer guidance on these acronyms. After all, they’re only purpose appears to be how to market variants of LAMP. The variants that I’ve seen for LAMP (Linux) are: MAMP (Mac OS X), SCAMP (Santa Cruz Operation), SAMP (Solaris), OAMP (OpenBSD, and WAMP (Windows) for MySQL database versions. The key seems to be swapping the first letter. I’ve only seen OPAL (Linux) officially for a LAMP stack that uses an Oracle database on a Linux platform. While my OPAW leverages what I perceive as a possible pattern, it may be wrong. Does anybody know what the right way to label these is?
Zend Java Bridge 32-bit
I just wanted to see how Zend Server Community Edition might be broken. Performing a full feature install on Windows x64, I confirmed that Zend Server’s Java Bridge depends on the 32-bit JRE (common sense prevails). Installing it against the JRE 64-bit jvm.dll did raised an exception but none of the instructions address the problem.
It’s one of those simplifying assumptions – everybody knows 32-bit software works with 32-bit software. Anybody running on Windows XP x64 should know that they may need a JDK 64-bit and both a JRE 64-bit and JRE 32-bit for some applications. For those who don’t know this, like my students and other newbies, when you run Windows XP the 64-bit stuff goes in the C:\Program Files
directory and the 32-bit stuff goes in the C:\Program Files (x86)
directory. This lets you develop 32-bit or 64-bit Java applications on the same 64-bit machine.
Another tidbit of interest, don’t choose a full install if you’ve already installed MySQL. The Zend Community Server isn’t smart enough to alter the configuration to another port, and their my.ini
points to a 3306
listener port. This causes the MySQL_ZendServer51 service to fail. It also doesn’t uninstall well. If you don’t want to clean the Windows Registry, don’t choose to install a second MySQL.
As an FYI, the Zend installation of MySQL doesn’t put a password on the root account. Don’t forget to add one after the install if you go down the full product road. This has the Zend Server Community Edition installation instructions.