Checking DNS records of a specific nameserver

I’m migrating a site from GoDaddy to HostGator (I personally would prefer to move over AWS but that’s the client’s choice in this specific case) and I wanted to get the IP of the new server on HostGator. I couldn’t find the IP anywhere on their control panel. Pinging the temporary URL they provide for testing was returning a different address — I suspect they have some kind of proxy in place for this temp URLs.

I know the host command could give me the DNS settings, which would include the A record with the IP address. However, the domain was still set to use GoDaddy’s nameservers (NS). Running host "name.tld" would give me the DNS records from GoDaddy. However, I was wondering if I could run the command against a specific nameserver. It makes sense having a way to look for records that way, right?

Looking at the man page for host command, there is a server argument. The signature looks like host [options] host [server]. So, I ended up running:

host -a "name.tld" "new.nameserver.tld"

And, voilà! I got the IP address for the new web server.

Got questions? Feel free to comment below.

Advertisements

Injecting controller actions in Laravel views

Disclaimer: Depending on the kind of logic you need, it’s also possible to use View Composers to achieve a similar result.

I’m using Laravel in this new project I’m working on. Some other PHP frameworks have a feature to use controllers as services. Symfony, for instance, has something like that. The project team thought Laravel, as Symfony-based, would have something like that. Well, if it has, it’s not clear in the docs.

Another team member ended up with a solution I never thought before:

 @inject('someController', 'App\Http\Controllers\SomeController')
 {!! $someController->index() !!}

Now, we’re using Blade’s @inject directive to call controller actions from inside views. That’s useful for reusing actions as widgets, for example.

If you find that interesting and want to use in your application, remember two things:

  1. Since you’re calling the action method directly, you have to pass all the required params. If it expects a request instance, you can do this: $someController->index(request()).
  2. Probably the method returns a view that contains HTML code. So wrap the call within {!! and !!}. Using the {{ }} regular tag will cause the code to be escaped.

Passing Node args to Mocha tests

This is a really quick tip. I was looking around on the internet for a way to pass Node arguments when calling Mocha binary. And I couldn’t find anything useful. Then I tried the following and it worked:

$ test node --expose-gc ./node_modules/.bin/mocha [...]

The --expose-gc argument is just an example. You can pass any argument accepted by Node program.

In my specific case, I was trying to load dotenv config. In the end, the project’s MakeFile looked like:

test:
    @NODE_ENV=test node -r dotenv/config ./node_modules/.bin/mocha \
        --require should \
        --reporter spec \
        --harmony \
        --bail \
        tests

.PHONY: test

Photo credit: Matt Benson

Testando comandos do Symfony que usam serviços da aplicação

Se você tem um comando no Symfony2 que usa serviços da aplicação, como um ORM por exemplo, e seguir o modelo que a documentação do framework fornece para escrever testes unitários, poderá ver erros com os a seguir:

Fatal error: Call to undefined method Symfony\Component\Console\Application::getKernel() in [...]/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.php on line [...]

ao acessar o kernel da aplicação, a partir do comando, ou:

Fatal error: Call to a member function getParameter() on a non-object in [...]

ao tentar acessar algum método do container.

O primeiro caso, acontece quando você usa a classe Symfony\Component\Console\Application ao invés de Symfony\Bundle\FrameworkBundle\Console\Application. Verifique os uses da sua classe de testes e ajuste se for necessário.

A segunda exceção é lançada quando você está usando a classe Application correta, mas usando um kernel inválido na sua instanciação. Talvez exista outro modo de fazer isso, mas para mim funcionou extender a classe Symfony\Bundle\FrameworkBundle\Test\WebTestCase no lugar de \PHPUnit_Framework_TestCase e construir a aplicação da seguinte forma:

$application = new Application(self::createClient()->getKernel());

Script de deploy para projetos que usam git

Há alguns meses atrás desenvolvi um script de deploy para um projeto em que estou trabalhando. Com o tempo vi a possibilidade de melhorar alguns pontos, especialmente com o uso do componente Console do Symfony2,  e agora disponibilizo uma versão pública que pode ser usada com projetos armazenados em um repositório git.

https://github.com/straube/deploy

Uma das limitações dessa versão é que ela trabalha apenas com SSH, mas em breve devo adicionar suporte a FTP.

Usando o APC para cachear variáveis no PHP

Sempre associei o APC (Alternative PHP Cache) ao cache de opcode no PHP, e somente a isso. Acredito que essa ligação seja natural para muitas pessoas, mas o APC pode ir além disso, cacheando qualquer variável dentro do PHP. Para isso existem algumas funções na extensão: apc_add, apc_fetch, apc_delete etc.

Para um experimento básico é possível usar apenas as funções apc_add e apc_fetch, seguindo o padrão de design lazy loading:

class City
{
    private $state;
    public function getState()
    {
        $cacheKey = 'state';
        if (false === ($state = apc_fetch($cacheKey))) {
            $state = ... // Buscar o estado de algum lugar, talvez do BD.
            apc_add($cacheKey, $state, 3600);
        }
        return $state;
    }
}

A primeira vez que a função getState é chamada, ela carrega o estado e armazena no cache, nas próximas chamdas a variável armazenada no cache será usada, evitando o acesso ao banco de dados. Passada uma hora (3.600 segundos) a variável é removida automaticamente do cache e na chamada seguinte ao método, o banco será consultado novamente. O tempo de vida (TTL) do cache pode ser alterado conforme as características da aplicação e do contéudo a ser cacheado.

Sobre as chaves

A chave usada para armazenar a variável no APC é global e compartilhada entre todas as aplicações em um mesmo ambiente. Isso pode ser interessante, porque o cache é compartilhado e, além da questão de otimização, pode ser um caminho para soluções que envolvem a troca de informações entre requisições ou programas distintos, mas também pode gerar bugs inesperados e difíceis de identificar se diferentes scripts PHP usarem a mesma chave para diferentes propósitos. Assim é sempre muito importante criar chaves com nomes distintos e exclusivos.