最初看了下PHP100的视频,因为这个网站最近比较火,大概在半年前,当时在前面几讲里做演示用的IDE是EasyEclipse,说是好用,于是我就选择了EasyEclipse。
看了两本书和一些视频之后,现在在研究几个PHP项目源码,突然发觉单步调试和变量追踪这样一些功能是必须要有的,否则根本没办法研究。可是在EasyEclipse里面没搞明白怎么弄,教程也搜不到。现在再去PHP100看视频教程发现用的是EclipsePHP Studio 2008
后来看到这个帖子:http://bbs.php100.com/read-htm-tid-8935.html于是装了 Eclipse for PHP Developers。可是打开后得到错误:Could not open the editor: No editor descriptor for id net.sourceforge.phpeclipse.PHPUnitEditor去google搜索解决办法,却又搜到PHPEclipse,现在完全搞不清楚这么多IDE到底哪个是哪个。谁能推荐个真正好用的IDE啊?谢谢啦。

解决方案 »

  1.   

    PHP调试需要Xdebug扩展,光有IDE是不够的
      

  2.   

    http://www.eclipse.org/downloads/packages/eclipse-php-developers/heliossr1
      

  3.   

    netbeans我是比较喜欢的。EclipsePHP Studio 2008 用过 感觉不好用!但是如果算最喜欢,我还是比较喜欢editplus 简单,不复杂!
      

  4.   


    这个我装了。一打开就看到这个:Could not open the editor: No editor descriptor for id net.sourceforge.phpeclipse.PHPUnitEditor
    org.eclipse.ui.PartInitException: No editor descriptor for id net.sourceforge.phpeclipse.PHPUnitEditor
    at org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:601)
    at org.eclipse.ui.internal.EditorReference.createPart(EditorReference.java:465)
    at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
    at org.eclipse.ui.internal.EditorAreaHelper.setVisibleEditor(EditorAreaHelper.java:271)
    at org.eclipse.ui.internal.EditorManager.setVisibleEditor(EditorManager.java:1429)
    at org.eclipse.ui.internal.EditorManager$5.runWithException(EditorManager.java:942)
    at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
    at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4041)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3660)
    at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
    at org.eclipse.ui.internal.Workbench$31.runWithException(Workbench.java:1567)
    at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
    at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4041)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3660)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2548)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
    at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
      

  5.   

    不过我在装这个版本的Eclipse之前,有装过普通版本的Eclipse(当时写Java)、MyEclipse、和EasyEclipse,不知道跟这个问题有关系没有~~~
      

  6.   

    这些没关系。 打开网页看右边Download Links
      

  7.   

    Eclipse 可以独立存在。 没有java环境下个 jre 包放在eclipse文件下即可
      

  8.   


    我就是點了右邊的Windows 32-bit那個版本,然後下載,然後安裝的。
      

  9.   

    http://blog.csdn.net/79720699/archive/2008/02/28/2131305.aspx
      

  10.   


    不關Java環境的問題吧,html的編輯器就有。只是沒有PHP的。
      

  11.   

    我覺得是PHP的Plugin配置有問題但不知道具體是怎麼回事。
      

  12.   

    我機器的環境是之前的同事獨立安裝的PHP和Apache。我打開php.ini,結果發現裏面居然沒有zend_extension_ts。難道一定要是XAMPP才行麼~~~
      

  13.   

    php 的调试环境我就没装,前断时间装了xDebug的环境没成功,我的不是windows系统,  
    直接echo或者 var_dump 就可以
      

  14.   

    因為我是入門級,所以看那個混在html里不習慣,而且很多時候終究是效率低,項目很大很複雜的話,就比較麻煩了,每個想檢查變量值的地方都要為每個變量寫一次我覺得這個不是長久之計啊
      

  15.   

    哎,这个问题拖延下去也是死结,我最终决定接受ihefe的建议。不过鉴于 var_dump 本身的输出不适合HTML情况,所以我想自己重新写个按照html语义格式化输出的函数,可是后来在PHP.NET上面发现原来好多人已经写了这样的东东,那么我就全部拿来,逐个逐个试用一番,最后选了几个比较好用的函数,把它们统一放在一个inspectVars.php文件里:<?php
    /*
     * Created on 2011/1/6
     * by Vincent
     * Collection of functions that work for inspection of variables
     * From PHP.NET
     * http://php.net/manual/en/function.var-dump.php
     *///Work well for HTML envirement:function variable_to_html($variable) {
        if ($variable === true) {
            return 'true';
        } else if ($variable === false) {
            return 'false';
        } else if ($variable === null) {
            return 'null';
        } else if (is_array($variable)) {
            $html = "<table border=\"1\">\n";
            $html .= "<thead><tr><td><b>KEY</b></td><td><b>VALUE</b></td></tr></thead>\n";
            $html .= "<tbody>\n";
            foreach ($variable as $key => $value) {
                $value = variable_to_html($value);
                $html .= "<tr><td>$key</td><td>$value</td></tr>\n";
            }
            $html .= "</tbody>\n";
            $html .= "</table>";
            return $html;
        } else {
            return strval($variable);
        }
    }////////////////////////////////////////////////////////
    // Function:         dump
    // Inspired from:     PHP.net Contributions
    // Description: Helps with php debuggingfunction dump_highstrike(&$var, $info = FALSE)
    {
        $scope = false;
        $prefix = 'unique';
        $suffix = 'value';    if($scope) $vals = $scope;
        else $vals = $GLOBALS;    $old = $var;
        $var = $new = $prefix.rand().$suffix; $vname = FALSE;
        foreach($vals as $key => $val) if($val === $new) $vname = $key;
        $var = $old;    echo "<pre style='margin: 0px 0px 10px 0px; display: block; background: white; color: black; font-family: Verdana; border: 1px solid #cccccc; padding: 5px; font-size: 10px; line-height: 13px;'>";
        if($info != FALSE) echo "<b style='color: red;'>$info:</b><br>";
        do_dump($var, '$'.$vname);
        echo "</pre>";
    }////////////////////////////////////////////////////////
    // Function:         do_dump
    // Inspired from:     PHP.net Contributions
    // Description: Better GI than print_r or var_dumpfunction do_dump(&$var, $var_name = NULL, $indent = NULL, $reference = NULL)
    {
        $do_dump_indent = "<span style='color:#eeeeee;'>|</span> &nbsp;&nbsp; ";
        $reference = $reference.$var_name;
        $keyvar = 'the_do_dump_recursion_protection_scheme'; $keyname = 'referenced_object_name';    if (is_array($var) && isset($var[$keyvar]))
        {
            $real_var = &$var[$keyvar];
            $real_name = &$var[$keyname];
            $type = ucfirst(gettype($real_var));
            echo "$indent$var_name <span style='color:#a2a2a2'>$type</span> = <span style='color:#e87800;'>&amp;$real_name</span><br>";
        }
        else
        {
            $var = array($keyvar => $var, $keyname => $reference);
            $avar = &$var[$keyvar];        $type = ucfirst(gettype($avar));
            if($type == "String") $type_color = "<span style='color:green'>";
            elseif($type == "Integer") $type_color = "<span style='color:red'>";
            elseif($type == "Double"){ $type_color = "<span style='color:#0099c5'>"; $type = "Float"; }
            elseif($type == "Boolean") $type_color = "<span style='color:#92008d'>";
            elseif($type == "NULL") $type_color = "<span style='color:black'>";        if(is_array($avar))
            {
                $count = count($avar);
                echo "$indent" . ($var_name ? "$var_name => ":"") . "<span style='color:#a2a2a2'>$type ($count)</span><br>$indent(<br>";
                $keys = array_keys($avar);
                foreach($keys as $name)
                {
                    $value = &$avar[$name];
                    do_dump($value, "['$name']", $indent.$do_dump_indent, $reference);
                }
                echo "$indent)<br>";
            }
            elseif(is_object($avar))
            {
                echo "$indent$var_name <span style='color:#a2a2a2'>$type</span><br>$indent(<br>";
                foreach($avar as $name=>$value) do_dump($value, "$name", $indent.$do_dump_indent, $reference);
                echo "$indent)<br>";
            }
            elseif(is_int($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color$avar</span><br>";
            elseif(is_string($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color\"$avar\"</span><br>";
            elseif(is_float($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color$avar</span><br>";
            elseif(is_bool($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color".($avar == 1 ? "TRUE":"FALSE")."</span><br>";
            elseif(is_null($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> {$type_color}NULL</span><br>";
            else echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $avar<br>";        $var = $var[$keyvar];
        }
    }// An elegant dump
    // By [email protected]
    $elegant_dump_indent = '|&nbsp;&nbsp;&nbsp;&nbsp';
    function elegant_dump(&$var, $var_name='', $indent='', $reference='') {
        global $elegant_dump_indent;
        $reference=$reference.$var_name;    // first check if the variable has already been parsed
        $keyvar = 'the_elegant_dump_recursion_protection_scheme';
        $keyname = 'referenced_object_name';
        if (is_array($var) && isset($var[$keyvar])) {
            // the passed variable is already being parsed!
            $real_var=&$var[$keyvar];
            $real_name=&$var[$keyname];
            $type=gettype($real_var);
            echo "$indent<b>$var_name</b> (<i>$type</i>) = <font color=\"red\">&amp;$real_name</font><br>".br;
        } else {        // we will insert an elegant parser-stopper
            $var=array($keyvar=>$var,
                       $keyname=>$reference);
            $avar=&$var[$keyvar];        // do the display
            $type=gettype($avar);
            // array?
             if (is_array($avar)) {
                $count=count($avar);
                echo "$indent<b>$var_name</b> (<i>$type($count)</i>) {<br>".br;
                $keys=array_keys($avar);
                foreach($keys as $name) {
                    $value=&$avar[$name];
                    elegant_dump($value, "['$name']", $indent.$elegant_dump_indent, $reference);
                }
                echo "$indent}<br>".br;
            } else
            // object?
             if (is_object($avar)) {
                echo "$indent<b>$var_name</b> (<i>$type</i>) {<br>".br;
                foreach($avar as $name=>$value) elegant_dump($value, "-&gt;$name", $indent.$elegant_dump_indent, $reference);
                echo "$indent}<br>".br;
            } else
            // string?
            if (is_string($avar)) echo "$indent<b>$var_name</b> (<i>$type</i>) = \"$avar\"<br>".br;
            // any other?
            else echo "$indent<b>$var_name</b> (<i>$type</i>) = $avar<br>".br;        $var=$var[$keyvar];
        }
    }//Work well for plain text envirement, better for log:
    function var_log(&$varInput, $var_name='', $reference='', $method = '=', $sub = false) {    static $output ;
        static $depth ;    if ( $sub == false ) {
            $output = '' ;
            $depth = 0 ;
            $reference = $var_name ;
            $var = serialize( $varInput ) ;
            $var = unserialize( $var ) ;
        } else {
            ++$depth ;
            $var =& $varInput ;    }    // constants
        $nl = "\n" ;
        $block = 'a_big_recursion_protection_block';    $c = $depth ;
        $indent = '' ;
        while( $c -- > 0 ) {
            $indent .= '|  ' ;
        }    // if this has been parsed before
        if ( is_array($var) && isset($var[$block])) {        $real =& $var[ $block ] ;
            $name =& $var[ 'name' ] ;
            $type = gettype( $real ) ;
            $output .= $indent.$var_name.' '.$method.'& '.($type=='array'?'Array':get_class($real)).' '.$name.$nl;    // havent parsed this before
        } else {        // insert recursion blocker
            $var = Array( $block => $var, 'name' => $reference );
            $theVar =& $var[ $block ] ;        // print it out
            $type = gettype( $theVar ) ;
            switch( $type ) {            case 'array' :
                    $output .= $indent . $var_name . ' '.$method.' Array ('.$nl;
                    $keys=array_keys($theVar);
                    foreach($keys as $name) {
                        $value=&$theVar[$name];
                        var_log($value, $name, $reference.'["'.$name.'"]', '=', true);
                    }
                    $output .= $indent.')'.$nl;
                    break ;            case 'object' :
                    $output .= $indent.$var_name.' = '.get_class($theVar).' {'.$nl;
                    foreach($theVar as $name=>$value) {
                        var_log($value, $name, $reference.'->'.$name, '->', true);
                    }
                    $output .= $indent.'}'.$nl;
                    break ;            case 'string' :
                    $output .= $indent . $var_name . ' '.$method.' "'.$theVar.'"'.$nl;
                    break ;            default :
                    $output .= $indent . $var_name . ' '.$method.' ('.$type.') '.$theVar.$nl;
                    break ;        }        // $var=$var[$block];    }    -- $depth ;    if( $sub == false )
            return $output ;}
    ?>
      

  16.   

    下面是测试文件driver.php:<?php
    require('inspectVars.php');$meeting = array(
        'title' => 'Sales Meeting',
        'start_time' => array(
            'hours' => 11,
            'minutes' => 15,
            'ampm' => 'am'
        ),
        'end_time' => array(
            'hours' => 1,
            'minutes' => 30,
            'ampm' => 'pm'
        ),
        'attendees' => array(
            array('first_name' => 'Bob', 'last_name' => 'Smith', 'email' => '[email protected]'),
            array('first_name' => 'James', 'last_name' => 'Andrews', 'email' => '[email protected]'),
            array('first_name' => 'Tom', 'last_name' => 'Schmoe', 'email' => '[email protected]')
        )
    );
    echo variable_to_html($meeting);
    echo dump_highstrike($meeting);
    echo elegant_dump($meeting);
    ?>输出效果分别为:variable_to_html:
    dump_highstrike:
    elegant_dump:另外,我又写了个针对非复合变量的格式化输出函数,其实这个也是复用了不少PHP.NET上的代码。print_primary_vars.php:<?php  function print_primary_var(&$var, $scope=false, $prefix='unique', $suffix='value')
      {
       //echo $var;
       $html = "<table border=\"1\">\n";
       $html .= "<thead><tr><td><b>NAME</b></td><td><b>TYPE</b></td><td><b>VALUE</b></td></tr></thead>\n";
        $html .= "<tbody>\n";
        $html .= "<tr><td>";
        $html .= vname(&$var, $scope=false, $prefix='unique', $suffix='value');    if (is_bool($var)) {
            $type = "BOOL";
            if ($var === true)
            {
             $valStr = 'true';
         }
         else if ($var === false)
         {
             $valStr = 'false';
            }
        } else if (is_int($var)) {
            $type = "INT";
            $valStr = $var;
        } else if (is_float($var)) {
            $type = "FLOAT";
            $valStr = $var;
        } else if (is_string($var)) {
            $type = "STRING";
            $valStr = $var;
        } else if (is_null($var)) {
            $type = "NULL";
            $valStr = "NULL";
        } else if (is_array($var)) {
            $type = "ARRAY";
            $valStr = "Dont call me please. Use inspectVars instead.";
        } else if (is_object($var)) {
            $type = "OBJECT";
            $valStr = "Dont call me please. Use inspectVars instead.";
        } else {
            $type = "UNKNOWN";
            $valStr = $var;
        }
    $html .= "</td><td>$type";
        $html .= "</td><td>$valStr</td></tr>\n";
        $html .= "</tbody>\n";
        $html .= "</table>";
        return $html;
      }  function vname(&$var, $scope=false, $prefix='unique', $suffix='value')
      {
        if($scope)
         $vals = $scope;
        else
         $vals = $GLOBALS;    $old = $var;
        $var = $new = $prefix.rand().$suffix;
        $vname = FALSE;    foreach($vals as $key => $val)
        {
          if($val === $new) $vname = $key;
        }    $var = $old;
        return $vname;
      }
    ?>
    使用方法为:<?php
      $my_global_variable = false;
      echo print_primary_var($my_global_variable); // Outputs:  my_global_variable  function my_local_func()
      {
        $my_local_variable = "My local string.";
        return print_primary_var($my_local_variable, get_defined_vars());
      }
      echo my_local_func(); // Outputs: my_local_variable  class myclass
      {
        public function __constructor()
        {
          $this->my_object_property = "My object property  string.";
        }
      }
      $obj = new myclass;
      echo print_primary_var($obj->my_object_property, $obj); // Outputs: my_object_property
    ?>当然,其实你可以把inspectVars.php和print_primary_vars.php两个文件合在一起,然后用require_once引用一下就可以了。希望对各位有用。
      

  17.   

    重发一次贴图:variable_to_html:
    dump_highstrike:
    elegant_dump:
    至于inspectVars.php中的var_log函数,它只适合于输出到一个纯文本的情况,比如写到log文件里。