Tag Archives: Zend-studio

Debugging a PHP CLI script

I’m working on some code on the command line that I needed to debug.  It’s on a remote machine (well, a VM that doesn’t have a GUI) and so I needed to initiate a remote debugging session from the command line to go to my local copy of Zend Studio.  Thankfully, it’s pretty easy.  Since I need a place to store this command so I can copy and paste it onto the CLI I figured I’d simply blog about it.  Simply execute  this command prior to executing your PHP script.

export QUERY_STRING="start_debug=1&debug_stop=1&debug_fastfile=1&
debug_coverage=1&use_remote=1&send_sess_end=1&debug_session_id=2000&
debug_start_session=1&debug_port=10137&debug_host=192.168.0.254"

The only thing you will need to change is the debug_host setting and perhaps debug_port.  Run your CLI script and the debugger will attempt to connect to your local Zend Studio instance.  If you want to discontinue debugging you execute this command.

unset QUERY_STRING

Connecting to PHPCloud.com through Zend Studio 9

PHPCloud.com is the landing page for our new cloud offering.  Using the Zend Application Fabric you can build your applications in the same environment as you will be deploying your apps to.  The application is built on my.phpcloud.com and you can then deploy it onto any platform where the Fabric is supported.

But how do you get started?  Phpcloud.com has been built in a way where you can connect with any IDE.  With Zend Studio 9 that connectivity has been built directly in to the IDE.

Getting started is actually quite easy.

Step 1 – Create a new project

Step 2 – Give that project a name!

Unlike with local development it really doesn’t matter where you put the project, it’s not going to be deployed locally anyway.  By default you will be given two options, the document root of the local server or the workspace.

 

Step 3 – Configure deployment options

This is where you connect up with phpcloud.  You are not going to be deploying to a production server.  The DevCloud (the thing you’re connecting to) is NOT a production box (I will go over this many times until you GET IT! :-) ) .  The first time you deploy your application it will do a full deployment to phpcloud.com it will do a full deployment.  Then as part of that deployment an SFTP connection will be set up and any time you save a file it will automatically uploaded.  The first full deployment is not done now, it is done later on.  This just sets it up.

If you do not have an existing PHPCloud.com connection set up for Studio you will need to enter in the username and password for PHPCloud.com as well as specifying your private key.  If you forgot to save the one that you were given you can always generate a new one from the UI.

 

 

 

Step 4 – Write Code

Ahhh.  Geek nectar.  Code.  Write some code.  If you have already deployed your application this code will automatically be uploaded to your container.

 

 

Step 5 – Launch the app

On the deployment page (double-click deployment.xml) click on the Launch a PHP application link.

Step 6 – Specify deployment params

Prior to launching the application you will need to specify the container that you want to deploy to as well as the URL.

 

Step 7 – Admire your work

Once the application has deployed it will be brought up in Studio’s default browser.

 

 

 

 

 

 

Addressing Zend Studio’s cost, minimal though it is

On the ZF-general mailing list there was a discussion that was occuring about the cost of Zend Studio.  I started writing a response but saw that it was getting kind of long so I decided to turn it into a blog posting.

The first question I'll address is that of cost.  When you look at what other similarly-featured IDE's cost, we're actually pretty good.  Flash Builder 4 is $250 for the standard, $800 for the premium version.  Visual Studio is $300.  IntelliJ is $599.  So, from an Apples-Oranges, throw everyone in the same bucket, IDE comparison, Studio is about where everyone else is, or better, from a pricing perspective.

Concerning the IDE's out there that are in the $100 range.  If all you're looking for are things like code completion and debugging, save yer hundred bucks and get PDT, which we provide for free.  It will provide most, if not all, of the same functionality in the $100 IDE.  You can download that free IDE (PDT) from eclipse.org, which is, if I didn't say it already, is free.

But now let's talk a little bit about what you get in Zend Studio, which is not free.

  • Solid refactoring.  I had one guy tell me this was the only justification he needed for the cost
  • Profiling.
  • Integrated support for Dojo, JQuery, Prototype and ExtJS.
  • Inline debugging of both PHP and JavaScript simultaneously
  • Integrated, in-the-IDE, unit testing.  In other words, re-run your test by hitting F11
  • VMware workstation integration
  • Zend Server integration.  You NEED to look at Code Tracing.
  • Enhanced remote system support.  Some of this is there, but there are some cool new features coming
  • The best Zend Framework integration/introspection you can get.
  • Mylyn support.  This is KILLER if you have any level of task/project management, which you should be using.
  • Support. 

Then, what I think is the killer; the Eclipse Community.  IF there is an IDE tool available it WILL be available for Zend Studio because if an IDE tool is available it WILL be available for Eclipse.  Almost no other IDE platform can say that.  The Eclipse ecosystem is unparallelled among IDEs.  For example, I manage all of my development EC2 instances right from inside Zend Studio because Amazon wrote a plugin for managing EC2 via an IDE.  Due to our relationship with Adobe I also use Flash Builder.  Flash Builder is built on top of Eclipse.  Therefore, my Zend Studio is also Zend Studio/Flash Builder.  I hit CTRL-F8 and I'm writing ActionScript.  Hit it again and I'm writing PHP.  I also have the Android SDK installed so I can run an Android emulator and connect it in with my PHP-based web site for mobile development.  Anything that is available as an Eclipse plugin is available for PDT/Zend Studio.

In terms of performance, there were performance problems in 6.  7 was better.  8 (current) actually has pretty decent performance.

Here's the way I think of it.  You spend your life in front of an IDE.  If there is ANY piece of software where a "commercial version" should be concidered it is your IDE.  Zend Studio costs $300.  There are 50 working weeks in the year.  That comes out to $6 a week.  Given an hourly rate of $50 an hour and a 40 hour work week.  If Zend Studio saves you 10 minutes of work per week it has paid for itself.

Now what you could do is find all the tools that do what you need them to do and use them.  But that means that you need to manage them.  When a new version comes out you need to test it against your existing tooling.  There might be a problem.  In fact, I think the whole discussion occurred because of an incompatibility between Zend Framework and the version of PHPUnit that was being used.  That's a great example.

Debugging a mobile app

I’m working on an example of mobile detection with the new Zend Framework 1.11 beta that was just released when I came upon an interesting problem.  That problem is; how do I debug requests coming in from the mobile phone?  The answer is actually relatively easy.  I’m doing this using a Zend Framework application, but the concepts that you’ll see here can be used quite easily across any type of framework.

The debugger in Zend Studio works by watching for certain cookies or GET parameters to be sent by the browser.  If they are detected then the Zend Debugger on the server will try to connect to the debugger in the IDE based off of the information provided in the cookie.  I typically do this using the Zend debugger toolbar, but I can’t get that on my Epic (Android).  Another option I have is to debug from the IDE but I’m not actually running from the phone so I will not have the same configuration.

The solution is similar to what I did with Debugging an RPC call in Zend Framework.  What this does is set the cookies from the remote browser to debug on the local instance of the Zend debugger.  To kick it off simply open up the URL to the debug kickoff page.  That will set the cookies in your mobile browser.  Then go to the page that you want to debug from your mobile phone and reload it.  Because you have the cookies set on the mobile browser the next request will debug in your local IDE.

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
class IndexController extends Zend_Controller_Action
{
 
    public function setdebugAction()
    {
        $cookies = array(
            'start_debug'            => '1',
            'debug_stop'             => '1',
            'debug_fastfile'         => '1',
            'debug_coverage'         => '1',   
            'use_remote'             => '1',
            'send_sess_end'         => '1',
            'debug_session_id'         => '2000',  
            'debug_start_session'     => '1',
            'debug_port'             => '10137',
            'debug_host'             => '127.0.0.1'
        );
        foreach ($cookies as $name => $value) {
            $this->_response->setHeader(
                'Set-Cookie',
                new Zend_Http_Cookie(
                    $name,
                    $value,
                    $this->_request->getHttpHost()
                    )
            );
        }
 
        $this->_helper->viewRenderer->setNoRender(true);
        echo "Debug set";
    }
}

 

 

Zend Studio trick #523

I learned a new tip for Zend Studio. When you have a long class like Zend_Application_Resource_Modules you can get code compltion on it by typing ZARM instead of the full name in the PHP editor.

ZARM

Flex and Zend Framework – Part 1

It would be a fair statement to say that I have not paid attention to Flash for several years.  Obviously I know that those awesome interfaces for movie web sites are made in flash, as are those annoying video ads that start screaming at you as soon as you load up a page, competing with Megadeth on Rhapsody, cranked out on the 700 watts of power I have in my office.  But the last time I really looked seriously at Flash was almost a decade ago and I was thrilled at tweening widgets from one place to another.  Unfortunately, there’s not really any benefit to tweening a text box. Cool? Yes. Practical? No.  So I never really picked it up.  Plus I was cheap.

That is the reason why I had not really been paying attention to Flash for the past several years.  I generally don’t look into something if it’s cool.  I look into something if it is practical.  Flash, generally, is meant to be, well, flashy.  And it is.  But for someone such as myself, I didn’t think I had much of a reason to pay attention.  Until now…

Given that Zend has had a professional relationship with Adobe for a while, I have been looking for the time to actually dive into what Flash was offering so I could make some kind of judgement call on it.  I realize that I am a little behind the times on it, but bear with me for a second.  A few weeks ago I decided that it was time for me to learn.  Partially it was because I wanted to learn it and partially it was because I needed to speak at Flash Camp Boston about integrating PHP and Flash.  There are few better motivators to learn something as when you are expected to be some kind of expert on it… or at least kinda know what you’re talking about.

With that in mind, I would like to talk about some introductory topics on what it would take to get a basic Flash/Flex application up and running.  This will be part 1 of an X part series.  I don’t know how many parts there will be, but I would expect that there would be a few.  We’ll probably keep on going until traffic to the postings starts to die down.  :-)

The first thing that you will want to do is get a copy of Flash Builder 4.  It was recently released and can be downloaded as a plugin for Zend Studio (technically, Eclipse).  You can download it from the Adobe website.  You can download it with a 60 day trial license.  That’s right.  60 days.   That is more than enough time to see if it’s something you want to do.  When I downloaded it, I did it as an Eclipse plugin on a fresh install of Zend Studio and it works like a breeze.

Once you’ve installed it, start up your instance of Zend Studio or PDT and switch to the new Flash perspective.  From there you can easily create a new Flash application by right clicking in your Package Explorer and selecting “New”.

New Flex ProjectWhen creating a new project using Flash Builder you will do so as a Flex Project.  The difference between Flex and Flash is kind of like the difference between Zend Framework and PHP.  Flex is a framework, Flash is the language/deployment platform.  Flex is the thing that really makes Flash practical as a more general front end. You can still make cool web sites for movies and recording artists, but it is Flex that really makes Flash worthwhile in my book because it adds a bunch of widgets that have practical business use… among other things.  So we create a Flex Project.

New Flex ProjectThe next step in the wizard is to set up some of the global options for your new Flex project.  The first two are self explanatory.  The next ones need a little explanation.

The first is the application type.  With Flash applications you have two different deployment platforms.  You can either run in the traditional web browser or you can also run it as a desktop application in Adobe AIR.  I don’t know exactly why it’s called AIR, but it seems eerily similar to Rich Internet Application.  Basically, that’s what it is.  It’s a desktop platform for Flash applications.  Apparently it is quite easy to move between the two.  I have not personally had a need to do that yet, so I don’t know exactly how it’s done.  But I have seen video of someone who took an AIR application and in about 15 seconds changed it to a mobile application.  Prett sweet.

I have personally built a web-based application using Flex and I’m in the middle of building one that is AIR based, both of which are used for this blog.  We’ll see if they end up being useful examples for PHP developers.

After the Application Type is the Server Technology.  This is where my primary interest lies. You can choose from ASP.NET, J2EE, Cold Fusion and PHP as your server technology.  Obviously, we are going to choose PHP.  What this means is that you can use Flash/Flex to create a very interactive front end for either your desktop or a browser while being able to keep your server side technology as PHP.

New Flex Project The PHP integration is done using the Zend Framework’s Zend_Amf components.  In order for Flash Builder to communicate with PHP it will install Zend Framework in a directory in your document root.  We can see that in the “Configure PHP Server” screen shot.  What it is doing is asking for the web root and the root URL so it can verify that it can reach its introspecter.

The introspecter is basically a Zend_Amf based gateway that can look at a certain class file and retrieve its class definition and create an AMF-based service which can then be worked with from within the Flash Builder IDE.  For applications that keep their class files in the document root of the web server this means that you can easily introspect those classes and interact with them in the IDE.  This is done via a file that the Flash Builder IDE installs in the Output Folder called gateway.php.  It contains a basic Zend_Amf_Server implementation.  However, if you have your code outside of the document root (which is generally recommended), the AMF remoting integration in the IDE can be a little problematic.  This is a bit of a problem as one of the really neat features of Flash Builder 4 is that you can take widgets that you place on the Flash canvas and inject data from your test environment in them.  You can kind of do this if your code is outside your document root or if you are using an MVC-based application but you need to hack up the generated code and Flash Builder likes to overwrite those hacks.  I will show you what you need to do, but first let’s do it the Flash Builder way.

MXML

No, not the number 2060 in Roman numerals.  Flash Builder uses an XML format to define its class structure, which I have to admit is kind of cool.  One of the benefits of this is that it seems to use XML validation to do syntax checking for the properties of various visual elements.  A basic MXML file will look something like this.

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:WindowedApplication>

As you can see; XML. But this is kind of useless. What we need is a label. The label will eventually be hooked up to an event that will cause it to look up the current time using an AMF service call. But before we set up the web service call let’s first set up our layout.

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
    <s:Label x="5" y="47" width="190" id="timeLabel"/>
</s:WindowedApplication>

You might be wondering how I knew to use s:Label.  It is because I dragged them from Components view in the IDE to the canvas.  Then I put the ID timeLabel in afterwards.  That will be important later on.  One of the really nice things about MXML is that its syntax very similar to HTML because of its relationship to XML, both of which are, of course, related to SGML.  What this means is that setting up the visual components to a Flex application is actually very easy for basic applications if you know how to use XML.

Remoting

The next step is to get the current time from the server.  To do that I will create a class called Time with a method called getTime() which will return a formated date/time string.  To make things easy for Flash Builder we will put it into the Output Folder which is C:workspaceBlogpublicEschradeReporting-debug for this application.

class Time
{
public function getTime()
{
return date('r');
}
}

Now we need to set up Flash Builder.  First we need to select the remote service type.

Selecting PHP

Then we need to introspect the class

Introspecting PHP

Next it will tell you which methods it has found.

Introspected method

At that point you are ready to use it.  You should be able to see it in the Data/Services view in Zend Studio.  You can right click on it and click Test Operation.  That will allow you to make sure that it’s working properly.

Testing the remoted object

As you can see, we were able to get a formatted response.  So now all that’s left is to bind this service to our label.  To do this we click on the getTime() service call and drag it on top of the empty label field.  When we do that we get a box like this.

Binding to the label

After you click OK, the IDE then adds a bunch of code to your file.

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:time="services.time.*">
    <fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.controls.Alert;

protected function timeLabel_creationCompleteHandler(event:FlexEvent):void
{
getTimeResult.token = time.getTime();
}

]]>
</fx:Script>
    <fx:Declarations>
<s:CallResponder id="getTimeResult"/>
<time:Time id="time" fault="Alert.show (event.fault.faultString + 'n' + event.fault.faultDetail)" showBusyCursor="true"/>

<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Label x="5" y="47" width="190" id="timeLabel" creationComplete="timeLabel_creationCompleteHandler(event)" text=" {getTimeResult.lastResult}"/>
</s:WindowedApplication>

There are a couple of things to go over here.  First is fx:Script.  This is the ActionScript code that is actually executed to get the call.  However, what you might notice is that it is not the value of the getTime() call that is returned, but a token.  These calls are done asynchronously.  So rather than blocking and waiting for a result, a token is passed to a special declaration called a CallResponder.  The CallResponder is just a declaration that is an integration point for data.  It acts as the meeting place for the service call and whichever listener is listening on the CallResponder.  That listener is denoted by "{getTimeResult.lastResult}" on the label widget.  So here is the order of execution.

  1. timeLabel_creationCompleteHandler() is registered as the handler for the creationComplete event.
  2. The createComplete event is fired and timeLabel_creationCompleteHandler is called
  3. The time.getTime() method is called which returns a token (we'll see this code in a bit)
  4. The async call to time.getTime() completes and the text property of timeLabel is updated to the value in the CallResponder getTimeResult.  lastResult is a property that contains the last service call result.

One last thing to note is the first thing you might have seen.  The time.getTime() method call has not been defined anywhere yet.  Or has it.  If we look at the s:WindowApplication element we see a new attribute called xmlns:time.  What this does is define the variable "time" to refer to services.time.*.  We will look at this code in just a bit.

When we run the Flash application in AIR we get the following output.

The final product

Working with ZF MVC

Now that we've done it the Flash Builder way we need to make some modifications to make it work with a Zend Framework MVC application.  Unfortunately, it won't work out of the box.  Yes, Flash Builder installs Zend Framework, but it doesn't do it in the context of an MVC application.  It also doesn't seem to check if Zend Framework is currently installed and places its own instance of Zend Framework in its Output Folder.  This doesn't affect your application, but you need to be aware of it so you can strip it out when you go to deploy your application.

In the earlier example we saw a reference to time.getTime().  That is defined in a java-like package, similar also to a PHP namespace.

The service

The actual code is defined in the _Super_Time.as file.  This is a pure ActionScript file whose syntax is very similar to Java.  In it is the code that actually makes the call.  There is a fair amount of autogenerated code in there.  I'll display it but only one line of code is actually important from a Zend Framework perspective.

package services.time
{
import mx.rpc.AsyncToken;
import com.adobe.fiber.core.model_internal;
import mx.rpc.AbstractOperation;
import mx.collections.ItemResponder;
import mx.rpc.remoting.RemoteObject;
import mx.rpc.remoting.Operation;
import com.adobe.fiber.services.wrapper.RemoteObjectServiceWrapper;
import com.adobe.fiber.valueobjects.AvailablePropertyIterator;
import com.adobe.serializers.utility.TypeUtility;

[ExcludeClass]
internal class _Super_Time extends RemoteObjectServiceWrapper
{

// Constructor
public function _Super_Time()
{
// initialize service control
_serviceControl = new RemoteObject();

var operations:Object = new Object();
var operation:Operation;

operation = new Operation(null, "getTime");
operation.resultType = String;
operations["getTime"] = operation;

_serviceControl.operations = operations;
_serviceControl.convertResultHandler = TypeUtility.convertResultHandler;
_serviceControl.source = "Time";
_serviceControl.endpoint = "http://eschrade/HelloWorldFlex-debug/gateway.php";
_serviceControl.destination = "Time";

model_internal::initialize();
}

public function getTime() : AsyncToken
{
var _internal_operation:AbstractOperation = _serviceControl.getOperation("getTime");
var _internal_token:AsyncToken = _internal_operation.send() ;

return _internal_token;
}

}

}

The _serviceControl.endpoint is the URL that the Flash app will go to get its information.  To make this work with a Zend Framework application we need to change it to where our Zend_Amf_Server implementation is.

First our model, in /application/models/Time.php

class Model_Time
{
public function getTime()
{
return date('r');
}
}

Then our controller in /application/controllers/ServiceController.php

class ServiceController extends Zend_Controller_Action
{
public function amfAction()
{
$srv = new Zend_Amf_Server();
$srv->setClass('Model_Time', 'Time');
echo $srv->handle();
}
}

Setting the alias "Time" for "Model_Time" is necessary because it matches the source and destination in our ActionScript file.  Then what we do is go back to our _Super_Time.as file and change the endpoint to

_serviceControl.endpoint = "http://eschrade/service/amf";

When we run it again, we get the same output.

Application Output

If our service endpoint defintion changes, meaning that our ZF model has some methods added or removed, then we need to re-introspect it.  To do that we will need to copy our model file to the Flash Output Folder directory and remove any pseudo-namespacing, such as Model_, reinstrospect it, delete it, and then go back in to the _Super_Time.as file and re-set the endpoint.  It's a little annoying, but it does work and it's not that big of a deal if you are working on classes whose public structure won't change much after the first introspection.  But it is something to be aware of if you are using an MVC application as your endpoint or if your class is outside of the document root.  Zend_Amf allows it, as does the gateway.php file that Flash Builder adds to the document root.  But it is the wizard in Flash Builder seems to require that any introspected files need to be in the document root.

That said, I have been working with Flash/Flex for several weeks and I am quite intrigued by many of the possibilities.  Over the next little while I will be adding to this series as I have time and inspiration.  But hopefully, this is enough to get you started.

 

[UPDATE]

Now I have 1020 watts of power in my office

Debug Tunneling

Debugging is one of the things that every single PHP developer in the world needs to know how to do.  Unless you are simply learning the language, learning how to debug will save you countless hours and save you loads of money in anti-anxiety medications.  var_dump() or print_r() is not debugging. At least, it's not debugging in a way that is very useful, or safe. 

There are two primary debuggers in the PHP world.  XDebug and the Zend Debugger.  I am not an expert in XDebug (though I really need to learn it better) so I will leave those discussions to someone else. 

Debugging on a local workstation is really quite simple.  I use the Zend Debugger Toolbar in my browser when I'm not debugging a Unit Test (how I usually test functional components, as opposed to visual components).  The reason I do this is because it's much easier to debug a certain context, such as a logged in admin user, than using the internal browser in Eclipse.  The toolbar is installed when you install Zend Studio or you can download it seperately and install it in Firefox manually.

The debugger toolbar

This works very easily when you are working in an environment with very few restrictions, such as a debug environment.  However, say you run into a problem in your testing or staging environments?  (I could also add your production environment, but you should actually never have the debugger installed on a production environment for security reasons.)  The way the debugger works is that Zend Studio opens up a port on the local machine so that when a debug session is kicked off, the debugger in PHP will open up a TCP connection back to Zend Studio and start the debug session.  The problem is that testing and staging environments often have outbound port restrictions, for good reason.  But that makes debugging an issue in one of those environments a little tricky.

The solution is the debug tunnel.  What Zend Studio does is instead of waiting passively on the local machine for a connection to come in, it will open up an HTTP connection to the remote server.  Then when a debug session occurs the debugger extension will communicate over a local port, which then forwards the debug information back to Zend Studio over HTTP.  The data is the same, it's just being tunneled over HTTP.  Because there is no outbound connection initiated and because the communication is occuring over port 80, if you can connect to the web server you can debug on it.  It should, however, be noted, that tunneling does not work on Windows systems.  I don't know the exact reason, but I would venture to say that it is due to PHP on Windows running as a FastCGI instance.  This would likely conflict with the long running request required to facilitate a debug tunnel.

The way this is done is by Zend Studio making a connection to a debug file.  That file is usually called dummy.php and contains the following code.

@ini_set('zend_monitor.enable', 0);
if(@function_exists('output_cache_disable')) {
        @output_cache_disable();
}
if(isset($_GET['debugger_connect']) && $_GET['debugger_connect'] == 1) {
        if(function_exists('debugger_connect'))  {
                debugger_connect();
                exit();
        } else {
                echo "No connector is installed.";
        }
}
?>

This code turns off all of the timers in monitoring, disables the cache and then checks to see if a debug tunnel is being requested.  If so, it basically sites on the debugger_connect() function.  This function will open up a port on the local interface and wait for connections to come in.  This file does not need to be on the domain name of the web site you are trying to debug.  In fact, just so you are sure that you don't accidentally deploy the dummy.php file it would be a good idea to have a seperate virtual host on the Apache server where it would reside.

On the Zend Studio side what you now need to do is set up the tunneling.  That is done by clicking on the arrow next to the tunneling button and clicking on "Servers".

Step 1

Clicking the Server button

Step 2

Selecting the server

Step 3

Enabling the tunnel

Step 4

Enabling the tunnel.

Step 5.

All done

With that, you should be golden.  Or in this case, green.

If you are using the Zend Studio toolbar you can test to actually see this working.  Simply go to Extra Stuff -> Settings and click on "Test".  You should see something similar to this.

Testing the connection

Go to your Linux server and then type in "lsof -i | grep |PORT|" replacing |PORT| with the port in the window.  In my case, 57192.

httpd     3016     apache    8u  IPv4 4100270       TCP *:57192 (LISTEN)

As you can see we have a connection setting there.  If we now do the same thing, but grep for the PID (3016) you can see our connection via our tunnel.

httpd     3016     apache    7u  IPv6 4100269       TCP li114-69.members.linode.com:http->xxxxxxxxxx:news (ESTABLISHED)
httpd     3016     apache    8u  IPv4 4100270       TCP *:57192 (LISTEN)

All done.

Zend Studio and PDT Code Completion Tips

Code Assist is one of those "must have" features in any IDE.  Some developers are so brilliant and have such good memories that they are able to know what parts of their application do what and those silly drop down boxes just get in their way.  I am not one of those developers.  I love Code Assist.  In fact, I learned Java via code completion in JBuilder 8.  It was horrible Java code, but it worked.  And eventually I learned how to write good Java… using code completion as well.

The concept of code completion is very easy to implement when you have a statically typed language.  It's not really a question of IF you will get a certain type of variable.  You WILL get it.  A dynamically typed language is a bit different.  You can have structure, but only if you decide to follow it.  I think this is a good thing.  There are many problems that don't need to have a highly structured solution.  In fact, most problems you need to solve on the web don't really need a highly structured solution.  That's one of the reasons, in my opinion, why PHP is so popular.  You can have the structure if you need it, but if you don't need it you don't need to use it.  That's also one of the reasons why I don't like rigid frameworks.

So, if you're going to give your PHP application more structure, how do you tell other developers about it?  When using Zend Studio or PDT comments are your friend.  Not just any comments, but PHPDoc.  With that you are able to both document your code and also provide hints to the IDE about what your return types are.

Let's start with a class

class User
{
    public function getParent()
    {
        if ($this->_parent) {
            return $this->_parent;
        }
        return null;
    }    
}

Now let's try some code completion on it.

Easy enough.  But what if you want to get the parent of the parent?

Parent of parent

Nothing.  And how should it?  The IDE has nothing to base the return type on and so has nothing to provide.  So how can you tell the IDE?  With PHPDoc.

class User
{
    /**
     * @return User
     */
    
    public function getParent()
    {
        if ($this->_parent) {
            return $this->_parent;
        }
        return null;
    }    
}

As you can see, we simply added @return User to our PHPDoc.  Now when we try out code completion we get

With Code Assist

Piece of cake.  But, what if we have code like this?

foreach ($users as $user) {
    $user->
}

We know that $user is an instance of User but the IDE doesn't.  However, what we can do is tell the IDE what the variable type is inline with the code.

Inline code completion

The code /* @var $user User */ provides information that the IDE can use to give you the code completion you need.  It is a simple multiline C comment with a tag @var in it.  Following the tag, the name of the variable is provided, in this case $user.  Then the variable type is provided. 

Easy.

Two imperative Zend Studio commands

In a perfect world software works all the time…

So, you can stop laughing now.  But if something gets really messed up there are a couple of options that you have to make it work again. 

Often, one of the reasons for a hung instance of Zend Studio is a broken workspace.  Zend Studio, and Eclipse, cache a LOT of information and the IDE is highly dependent on that information.  Sometimes that information gets royally mangled.  If the workspace is salvagable, and it usually is, the easiest way to fix the problem is to have Studio clean its cache.

First open up a command prompt (or terminal in Linux)

Command prompt

If all you need to do is re-cache everything all you need to do is go to your Zend Studio installation directory and type in ZendStudio.exe -clean

Calling -clean

When you start up Studio it will re-cache all of the information that it had before.  Usually this will work.

However, sometimes your system is just hosed and the current workspace is unusable.  Studio will basically not start up because it is unable to load the workspace.  Sometimes, though rare, this means that Studio will not start up at all.  But fear not.  The solution to this problem is to start Studio in a different workspace which can be done by using the -data switch.

Starting up using -data

The workspace that you specify does not even have to be an actual Studio workspace.  It can just be an empty directory.  That will usually be enough to get you up and running, at least minimally.

Server Monitoring, Studio Tasks and Gmail?

I deployed this blog about a week ago.  Since then there has been little traffic, mostly  because I have not promoted it and I have also been working on a bunch of other content and such.  Since I also just needed to just get it out the door and running I have not spent a lot of time testing for performance.  This blogging app is based off of Zend_Application and as such there is a bit of overhead.  Since I was not expecting traffic to be that heavy I was not (and am not) overly concerned about snappy performance at this point.  As long as the page loads and displays in the browser I’m fine with it.

One of my goals with this blog is to show real life examples of how to use Zend Server.  While I am not overly concerned about the performance of this blog for the time being I am still monitoring it to make sure that it performs well.  That means Monitoring.

However, Monitoring is really not all that beneficial if you don’t know what is happening on your server.  To get around that issue, Monitoring has a feature where you can send an email to one or more email addresses when an event occurs, such as slow page load times or a fatal error.  This is great… except that people ignore emails.  We’re conditioned to.  As great as Spam in a can is (I’m not Hawaiian, but Spam is a delicacy IMHO), Spam in the Inbox has conditioned us to ignore the things we’re not interested in.  And, to be honest, we’re not interested in fixing problems.  We’d rather be doing new and cool things.

Task driven development is part of the Agile process.  Test driven development is too, but I’m going to talk about Task driven development.  What that basically means is that if there is something to be done, a task is created and it is worked on by the next available developer.  The benefit of this is that with short, well defined tasks, it is easy to track the progress that is being made on a project.  That is why task driven development is part of Zend Studio.

“What?  I thought you were talking about Monitoring?”  Yep.  Still am.  What I am going to show you is how you can integrate Monitoring with Zend Studio using Gmail to make you a better developer.

First, we need to set up our Gmail account.  Log in with your email address and go to Gmail’s “Settings” -> “Labels” section and create a new label called “Task”.

Create Label

Next, click on “Filters”.  Create a new filter and enter a “From” address; [email protected] in my case.  The actual email address is relatively unimportant, and doesn’t really need to exist, as mine doesn't.  What is important is that you can match it up with the “From” address that Monitoring will use, which we will set up later on.  Click on “Next Step” and tell it to apply the label “Task” to any message coming in from that email address.

Filter Step 1

Filter Step 2

Zend Studio has the ability to connect in with Mylyn task connectors.  To access this, go to the Planning perspective in Zend Studio.  On the right hand side you should see a View window that says “Task Repository”.  From there you can right click on the screen and select “Add Task Repository”.  You will be asked to choose a specific type of task repository.  I will use the Gmail type.  If you don’t have the Gmail connector installed click on “Install More Connectors” and install it from there.  You may need to restart Studio (“may” meaning you will need to).  You may (same thing) need to create a TaskTop account.  It seems to be free.

Add Repository

Once you’re back up, go back to the same view and get to the “Add Task Repository” window again.  This time select Gmail as the repository type.  Enter in your email address and your password, but set “Task” as the label.  Click Finish.

Add Label

Then you will probably get a window popping up asking if you want to configure a query.  Of course you do.  Set the title of the query as "Task" and then choose the label that you want to query by.  This should be the new label that you had entered earlier on.

Set Query

Next we will go into the Zend Server admin GUI.  Select “Server Setup” and then “Monitor”.  From there you should see some mail server settings.  The sender email address is the one you set up for the “from” address in the Gmail filter; [email protected] in my case.  Click Save.

Monitor Mail Settings

From there go to the “Rule Management” tab and select the rule that you want to receive alerts for.  Scroll down to “Step 2: Event Action”. Enter in your Gmail email address here, save it and restart PHP.  I chose Slow Request Execution.  And since slow requests are difficult to debug I also chose to enable Code Tracing when a slow request occurs.

Monitor Action

Now you wait for an event to occur.  Me?  I just refreshed the home page.  (I may have some optimizations to do).  Go back to the Planning perspective and right click on the task list and click “Synchronize”.  You should see a new task listed.  Double click on it and you should see something like the following.

Task Received

Now, rather than using your email program and ignoring messages that come in, you can have them directly integrated into a simple task management system.

Summary

  1. Create Label in Gmail called "Task" with a filter for the "From" address, set up in Zend Server
  2. Add Mylyn connector for Gmail and set up to use your Gmail account with the label "Task"
  3. Set up Zend Server Monitoring to send monitoring events from the "From" address
  4. For a specific event set it to send an email to your Gmail account
  5. Wait for events to come in.
  6. Fix them
Web Analytics