Back-End

10 mar, 2016

Trabalhando com Ionic e PHP Backends – depuração remota com PHP7 e Xdebug em dispositivos reais

Publicidade

Às vezes eu falo com os desenvolvedores de PHP e eles não usam a depuração remota em seus ambientes de desenvolvimento. Algumas pessoas não gostam de usar a depuração remota. Elas preferem usar TDD e contar com os testes unitários. Isso é um bom ponto de vista, mas às vezes elas não usam a depuração remota só porque não sabem como fazer, e isso é inadmissível. Depurador remoto é uma ferramenta poderosa, especialmente para lidar com aplicativos antigos. Eu estou usando Xdebug durante anos com a minha estação de trabalho Linux. Ultimamente estou usando Mac e também é muito simples de configurar Xdebug aqui.

Primeiro, precisamos instalar o PHP:

brew install php70

Então o Xdebug

brew install php70-xdebug

(No Ubuntu, só precisa usar o apt-get, em vez de brew)

Agora precisamos configurar o Xdebug para permitir a depuração remota: em uma instalação padrão, a configuração do Xdebug está localizada em: /usr/local/etc/php/7.0/conf.d/ext-xdebug.ini.

[xdebug]
zend_extension="/usr/local/opt/php70-xdebug/xdebug.so"
 
xdebug.remote_enable=1
xdebug.remote_port=9000
xdebug.profiler_enable=0
xdebug.profiler_output_dir="/tmp"
xdebug.idekey= "PHPSTORM"
xdebug.remote_connect_back = 1
xdebug.max_nesting_level = 250

E, basicamente, isso é tudo. Para definir/desativar o cookie, você pode usar um bookmarklet no seu navegador (você pode gerar seus bookmarklets aqui). Ou use uma extensão do Chrome para ativar o Xdebug.

Agora só precisamos iniciar o servidor embutido com

php -S 0.0.0.0:8080

E a depuração remota estará disponível. O depurador remoto funciona da seguinte maneira:

  • Abrimos na porta dentro da nossa IDE. No meu caso, PHPStorm (isso acontece quando eu clico em “Start listening for PHP debug connections”).
  • Configuramos um cookie no nosso navegador (isso acontece quando clico na extensão do Chrome).
  • Quando o nosso servidor recebe uma solicitação com o cookie, ele se conecta à porta que a nossa IDE abriu (normalmente a porta 9000). Se você usa um firewall pessoal na sua estação de trabalho, tenha certeza de permitir conexões de entrada para essa porta.

Atualmente, estou envolvido com vários projetos de construção de aplicações híbridas com Apache Cordova. No front end, estou usando ionic e Silex no backend. Quando eu estou trabalhando com aplicações híbridas, normalmente passo por duas fases.

Na primeira, eu construo um protótipo funcional. Para isso, eu uso um servidor local e meu navegador para desenvolver o aplicativo. Essa fase é muito semelhante a um processo de desenvolvimento web tradicional. Se nós também configurarmos corretamente o LiveReload, a nossa aplicação será recarregada cada vez que mudarmos um arquivo JavaScript. O framework Ionic integra LiveReload, e nós só precisamos executar:

ionic serve -l

para começar a nossa aplicação. Nós também precisamos iniciar o nosso servidor backend. Por exemplo:

php -S 0.0.0.0:8080 -t api/www

Agora nós podemos depurar o nosso backend com o depurador remoto e o front end com as ferramentas de desenvolvedor do Chrome. O Chrome também nos permite editar arquivos de front end e guardá-los dentro do sistema de arquivos usando workspaces. Essa fase é a fácil. Porém, mais cedo ou mais tarde, vamos precisar começar a trabalhar com um dispositivo real. Precisamos de um dispositivo real, basicamente se usarmos plugins como o de Câmera, Geolocalização, ou coisas assim. OK, existem emuladores, mas geralmente emuladores não permitem utilizar todos os plugins da mesma maneira como em um dispositivo real. O Chrome também nos permite ver os logs de console do dispositivo a partir de nossa estação de trabalho. OK, podemos ver todos os logs de nosso dispositivo Android conectado usando “adi logcat”, mas seguir o fluxo dos nossos registros com logcat é semelhante a entender o código da Matrix. É uma bagunça.

Se ligarmos o nosso dispositivo Android em nosso computador e abrir com o Chrome:

chrome://inspect/#devices

Podemos ver o console do nosso dispositivo, utilizar breakpoints e coisas assim. Legal, não é? É claro que ele só funciona se nós compilarmos nossa aplicação sem a opção “-release”. Nós podemos fazer algo semelhante com o Safary e dispositivos iOS.

Com ionic, se quisermos usar LiveReload no dispositivo real e não recompilar e reinstalar novamente e novamente nossa aplicação cada vez que mudarmos nossos arquivos JavaScript, podemos executar a aplicação usando

ionic run android --device -l

Quando estamos desenvolvendo nossa aplicação e estamos nessa fase, também precisamos lidar com CORS. CORS não é um problema quando executamos nossa aplicação híbrida em produção. Quando executamos a aplicação híbrida com o nosso dispositivo, a nossa “origem” é o sistema de arquivos local. Isso significa que CORS não se aplica, mas quando executamos nossa aplicação no dispositivo, porém o servidor está em nosso computador (quando usamos opção “-l”), nossa origem não é o sistema de arquivos local. Portanto, se o nosso backend é servido a partir de outra origem, precisamos ativar o CORS.

Podemos habilitar o CORS no backend. Eu escrevi sobre isso aqui, mas o pessoal do ionic nos fornece uma maneira mais fácil. Podemos configurar um proxy local para servir o nosso backend através da mesma origem que o aplicativo faz e esquecer CORS. Aqui podemos ler um bom artigo a respeito.

Enfim, se queremos iniciar o depurador remoto, precisamos criar um cookie chamado XDEBUG_SESSION. No navegador, podemos usar a extensão do Chrome, mas quando inspecionamos o dispositivo conectado não é tão simples. Seria legal que o pessoal do ionic nos permitisse injetar cookies no nosso servidor proxy. Eu tentei ver como fazer isso com ionic-cli. Talvez seja possível, mas eu não descobri como. Por causa disso, eu criei um serviço em AngularJS bem simples, para injetar esse cookie. Então, se eu começar a ouvir conexões de depuração no meu IDE, serei capaz de usar o depurador remoto tão bem quanto quando eu trabalho com o browser.

Primeiro, precisamos instalar o serviço por meio do Bower:

bower install ng-xdebugger --save

Agora precisamos incluir os arquivos JavaScript

<script src="lib/angular-cookies/angular-cookies.min.js"></script>
<script src="lib/ng-xdebugger/dist/gonzalo123.xdebugger.min.js"></script>

Em seguida, nós adicionamos o nosso serviço ao projeto.

angular.module("starter", ["ionic", "gonzalo123.xdebugger"])

Agora só precisamos configurar o nosso aplicativo e a chave do depurador (que deve ser a mesma chave que usamos dentro da configuração do lado do servidor do Xdebug).

.config(function (xdebuggerProvider) {
        xdebuggerProvider.setKey('PHPSTORM');
    })
})

E isso é tudo. O serviço é muito simples. Ele usa apenas um interceptor http para injetar o cookie em nossas solicitações http:

(function () {
    "use strict";
 
    angular.module("gonzalo123.xdebugger", ["ngCookies"])
        .provider("xdebugger", ['$httpProvider', function ($httpProvider) {
            var debugKey;
 
            this.$get = function () {
                return {
                    getDebugKey: function () {
                        return debugKey;
                    }
                };
            };
 
            this.setKey = function (string) {
                if (string) {
                    debugKey = string;
                    $httpProvider.interceptors.push("xdebuggerCookieInterceptor");
                }
            };
        }])
 
        .factory("xdebuggerCookieInterceptor", ['$cookieStore', 'xdebugger', function ($cookieStore, xdebugger) {
            return {
                response: function (response) {
                    $cookieStore.put("XDEBUG_SESSION", xdebugger.getDebugKey());
 
                    return response;
                }
            };
        }])
    ;
})();

E, claro, você pode ver o projeto inteiro em minha conta no GitHub.

***

Gonzalo Ayuso faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://gonzalo123.com/2015/12/14/working-with-ionic-and-php-backends-remote-debugging-with-php7-and-xdebug-working-with-real-devices/