Tuesday, November 02, 2010

New 10 Top Zend Studio 8.0 Features (applies mostly to Eclipse PDT 2.2.1)

After one and a half years of community development and Zend internal hard work, Zend Studio 8.0 is officially released today after 3 months in beta!

During the beta term I tweeted about the new features and I wanted to aggregate everything to one blog so you can all review it in one place.

  1. New Analyze Network Usage and Performance with Zend Studio 8.0 http://yfrog.com/3dc06xp #zendcon Top Studio new features #1
  2. New Running #php Applications on VMWare Workstation through Zend Studio 8.0 http://yfrog.com/69z0tp Top Studio new features #2
  3. New remote server support (ftp/ssh) http://bit.ly/9ei3hf Top Zend Studio new features #3
  4. New #phpunit configuration files support http://bit.ly/aN2w3e Studio new features #4
  5. New jQuery Support http://yfrog.com/7f1jap Top Studio new features #5
  6. New native installers http://yfrog.com/5i4itp Top Studio new features #6
  7. New content assist with templates http://yfrog.com/0r5j9p Top Studio new features #7
  8. New hover information box http://yfrog.com/6x26763202p - Top Studio new features #8
  9. New "Inspect" action in #php editor http://yfrog.com/5j3sssp - Top Studio new features #9
  10. Enhancements for Windows 7 http://yfrog.com/mlxu3p (thanks #mylyn) - Top Studio new features #10
I'll probably have another post about the guys at Zend and community that helped with this release, so stay tuned if you want to hear about the team.

Tuesday, September 07, 2010

Five (more) tips for speeding up Eclipse PDT

In a previous blog post written by Zviki Cohen, five simple tips were suggested to help Eclipse PHP Development Tools (PDT) users speeding up their development environment . I want to share five more tricks that can dramatically improve your experience with Eclipse and PDT. Not only these tips help speeding up performance but also make your PHP source code more controlled.

1. Exclude non-source-code folders and manage wisely your project buildpath - Buildpath is a set of paths indicating what folders should be scanned (built) by Eclipse. If the project Buildpath includes its root (for example) then all folders that include images, javascript , style sheets and other non-source related files are listed to the scanner. Although theoretically most of these files are not actually scanned since non-PHP content types files are skipped, Eclipse keeps track on changes and make some redundant operations on these folders that may contain thousands of irrelevant files, hence perform bad .

2. Setup project include path - to optimize the include/require statements path resolving it is more than useful to make sure that the project include path settings are set correctly. Representing the actual include path is a key to make things work smoothly.

3. External libraries are not part of your code, don't keep it under your project resources - this is a classic project configuration mistake. Make sure that frameworks and external libraries are not included under your project sources, instead link it to your project as a library. Eclipse can relate to these ("static"/"read-only") frameworks differently than your ("dynamic"/"writeable") code which is under constant development. Frameworks should be scanned once and not be part of your project source code.

4. Split your project into sub-projects and modules - it makes sense you separate your core business, services, client side interface, tests and other modules into different projects that have different natures and make the components more flexible and easy to be re-used and maintained by others. Often, I see PHP projects that include dozens of thousands of flat hierarchy source code that is hard to maintain and configure.

5. Share your project configuration files with your team. Configure your project once and make sure all team members follow the same conventions and management rules. These files are located under your project root (the dot files) and can be shared in your source code repository.

To summarize things "Mastering your development environment is as important as mastering your source code" - this concept is sometimes forgotten by scripting language developer who are used to a flat hierarchy source code. Although I consider this as a major strength of scripting languages it doesn't mean that project management should be flat...

Wednesday, May 12, 2010

How do you like to "use" it?

According to the PHP.net manual "PHP namespaces support two kinds of aliasing or importing: aliasing a class name, and aliasing a namespace name". So basically this leaves two options for the average case:

Aliasing a namespace name

namespace ns1\ns11\ns111 {
class c1 { }
namespace ns2\n21 {
use \ns1\ns11\ns111;
$v = new ns111\c1();

Aliasing a class name

namespace ns1\ns11\ns111 {
class c1 { }
namespace ns2\n21 {
use \ns1\ns11\ns111\c1;
$v = new c1();

While both options are useful developers will probably prefer to use the one over the other in different cases. For example if your script imports many classes declared in one namespace, only one namespace can be imported avoiding the need to import each class separately.

Option A:

use \ns1\ns11\ns111\c1;
use \ns1\ns11\ns111\c2;
use \ns1\ns11\ns111\c3;
use \ns1\ns11\ns111\c4;
use \ns1\ns11\ns111\c5;

$v = new c1(new c2(new c3(new c4(new c5()))))

Option B:

use \ns1\ns11\ns111;
$v = new ns111\c1(new ns111\c2(new ns111\c3(new ns111\c4(new ns111\c5()))))

How Eclipse PDT should complete your "use" statement?

A real cool feature in Eclipse PDT is that use statements are completed automatically for you. The question is what method should be considered:
1. Aliasing a class name
2. Aliasing a namespace name
3. Depends on the case, what are the different cases?

Vote here: http://twtpoll.com/omuaqn

Sunday, April 11, 2010

Thoughts on Flash (the Eclipse way)

Funny coincidence but definitely not related to Apple vs. Adobe shootout, my team was required to integrate an existing Adobe Flash application into Zend Studio 7.2.0 (an Eclipse PDT based product). Let's share this experience of integrating Eclipse and Flash:

Reusing Flash or Writing plain SWT?

It started as a simple and common requirement to provide a presentation layer for a given data source loaded into the product. Happy and enthusiastic we started designing a user friendly Eclipse perspective that provides nice diagrams and trees that present the data. Before we started to actually implement it, we were told that it would be great if we can reuse an existing Flash application that our colleges at Zend have already developed. "Adobe do this so why can't we do this?", relating to Flash Builder that is based on Eclipse and Flash. Anyway, it can save months of development and integration effort in the future.

The Good

Using a Flash application into Eclipse integrated web browser is pretty easy task. Users choose a source file in a dedicated import wizard, a new perspective is presented that includes an Eclipse view presenting the Flash application. We used a simple browser view for this end:

public class FlashView extends ViewPart {
private Browser browser;
public void createPartControl(Composite parent) {
parent.setLayout(new FillLayout());
try {
int mozilla = SWT.MOZILLA;
browser = new Browser(parent, mozilla);
} catch (SWTError e) {
// ...
private String getText(String file) {
return "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'
width='100%' height='100%'>
<param name='flashVars' value='...'>
<param name='src' value='myFlash.swf'>
<param name="wmode" value="opaque">
<embed pluginspage='http://www.macromedia.com/go/getflashplayer'
width='100%' height='100%'

And a Jetty server for serving the Flash application is launched:

public class JettyServerManager {

public static void startJettyServer(final int port) throws Exception {
final String rootPath = getJettyRootPath();
Runnable runnable = new Runnable() {
public void run() {
server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();

try {
} catch (Exception e) {
// ...
serverThread = new Thread(runnable);

public static void stopJettyServer() throws Exception {
if (server != null) {
// ...

The Bad

One more trick that we wanted to add in our client product is a small layer of communication between the two applications, so basically once a user clicks on a data relating to a specific workspace resource the relevant resource is opened in the editor (something like "link with editor" button).

Our first attempt used a dedicated socket to transfer these calls, but after reading the cross-domain policy we understood that another port is required. So three (!!!) different ports are opened for serving this application - the Jetty one, our communication channel and a cross-domain policy port (since the default one is 843 and Linux based OS can't open it we should have open another non-default one). We could live with it if it worked out, but after lots of testing it came out that Windows and Linux machines don't behave the same. On Windows the security port got the request and handles it right, then the actual communication port works as expected. On Linux the same workflow is expected but we got garbage content in our communication although the policy file was excepted and verified by the Flash engine.

Our next attempt used the same Jetty channel to broadcast the changes from the Flash application, once the Flash application wants to alert our product it sends a request to the Jetty (on the same port) and notify our product. This actually worked very nicely.

The Ugly

Well, let's say that Flash and SWT don't share the same look and feel and are naturally different. Usability in this case is a little awkward but tolerable.
To make sure our customers are not required to manually install a browser and then install a Flash player plugin on top of this browser we wanted to have our own XULRunner instance and flash player plugin installed. Although it seems that Adobe's Flash player license is pretty open we couldn't redistribute it in an easy way into our integrated browser as Adobe require to install it under a specific place using their installers.
One last usability shame is the case where an instance of a Flash view is opened and then Eclipse product is closed. Although the Jetty service is down as well (as expected) it should be launched again to serve the view again upon start.

The End Result

A simple import wizard that requires the stored snapshot is displayed:

Many thanks to Qiangsheng Wang and Jacek Pospychala!