Reativação do Blog

Prezados leitores,

Já alguns anos resolvi criar este blog para compartilhar minhas experiências profissionais e para servir de vitrine das minhas competências.

Muitas coisas mudaram e aconteceram desde 2011. Gostaria de contar mais das minhas aventuras acadêmicas e das competências adquiridas até agora.

Nas próximas semanas eu volto!

 

 

 

Publicado em Sem categoria | Deixar um comentário

Curso de Extensão Fatec Mococa: Desenvolvimento de Software para Web com HTML 5, CSS 3 e JavaScript

Olá Leitor!

Hoje trago uma novidade, vou lecionar um curso de extensão na Fatec Mococa, no curso pretendo abordar HTML 5, CSS 3 e JavaScript.  O curso terá duração de 3 meses, com aulas aos sábados. A carga horária de 40h.

Folder de divulgação do curso.

Nesta primeira empreitada o curso será grátis, sendo oferecidas 20 vagas (mas caso você tenha notebook, poderemos acomodar mais 7 participantes, totalizando 27). O início das aulas será no dia 01/09/2012 e o curo irá se estender até o dia 01/12/2012, sempre aos “sábados úteis” das 13:30 às 17h.

As inscrições serão entre 14/08 à 30/08/2012. Será oferecido certificado aos alunos aprovados no final do curso.

Abraços,

Tiago.

Publicado em Carreira, CSS, Cursos, Eventos, HTML 5, JavaScript, JQuery | Com a tag , , | Deixar um comentário

Criando Extensões para o PHP: Parte II – Configuração do Ambiente de Desenvolvimento no Windows

Olá Amigos!

Este é o segundo post da nossa série “Criando Extensões para o PHP“, até agora este foi o post que mais exigiu pesquisa e dedicação, trabalhei para que ele ficasse o mais enxuto possível e também irei descrever os erros de configuração e as respectivas respostas que tive ao longo do caminho. Antes de mais nada você precisa se certificar que está com o PHP instalado e funcionando. Em um post anterior eu sugeri um tutorial de instalação da mesma versão que estamos utilizando aqui, a 5.4.4, fique a vontade para atualizar. Acidentalmente durante a pesquisa para este trabalho encontrei outro tutorial de instalação mais completo e descrevendo algumas particularidades, vale a pena dar uma olhada.

Em nosso segundo post da série que aborda o desenvolvimento de extensões para o PHP (se você não viu o primeiro clique aqui) iremos configurar o ambiente de desenvolvimento no Windows e por fim obteremos nossa extensão na forma de uma DLL. Antes que os mais detalhistas digam que mencionei no post passado que trabalharíamos com extensões build-in eu acrescento que ao longo da pesquisa me deparei com este tipo de abordagem e acreditei ser mais válida a abordagem neste primeiro momento, já que sua implementação é mais simples.

Inicialmente pensei em utilizar o NetBeans como IDE, no entanto percebi que absolutamente ninguém o utilizava, e interessado em saber o porque descobri a lista de compiladores suportados pelo PHP no ambiente Windows, e ainda descobri que o compilador MinGW, que eu pretendia utilizar juntamente com o NetBeans é explicitamente não suportado. E assim levando em conta este fato com tom engraçado descobri ainda que a recomendação é utilizar o Microsoft Visual C++ para “buildar” o PHP no Windows, eu na minha eterna ingenuidade não havia (incrivelmente) ligado os pontos, já que vamos compilar o PHP para rodar em um produto Microsoft, nada melhor que utilizar um compilador Microsoft.

Bom, dadas as cartas na mesa, vamos ver o que iremos precisar neste momento:

.

1. Instalações e Configuração de Arquivos e Diretórios

Após ter em mãos todos os arquivos, instale:

  1. Microsoft Visual C++ 2008 Express Edition (pode ir tomar m café, demora um pouco).
  2. Microsoft Windows SDK for Windows 7 and .NET Framework.
  3. Crie uma pasta no C:/ denominada “php-dev”.
  4. Descompacte o arquivo de fontes do PHP para dentro do “php-dev” de maneira que os fontes fiquem acessíveis como: “C:/php-dev/php-5.4.4″
  5. Descompacte nossas bibliotecas Win32 Build Tools para dentro da pasta “php-dev”, de maneira que fique: “C:/php-dev/win32build”
  6. Copie o arquivo “bison.exe” de dentro de “C:/php-dev/win32build/bin” para “C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin”
.

1. Preparando o Ambiente de Desenvolvimento

No menu iniciar, abra o “Microsoft Visual Studio 2008 Command Prompt“. Vá até a pasta do código fonte do PHP, no nosso exemplo fica:

cd C:/php-dev/php-5.4.4

Agora vamos executar dos scripts, o buildconf.bat e configure.js. Esta etapa é importante pois vai criar alguns arquivos que serão incluídos em nosso projeto e resolver este erro no momento do Build:

Compiling...
stdafx.cpp
C:php-devphp-5.4.4-srcZendzend_config.w32.h(25) : fatal error C1083: Cannot open include file: '../main/config.w32.h': No such file or directory

Quando estava escrevendo este post tive o problema abaixo no momento da execução de ambos, veja:

c:php-devphp-5.4.4>buildconf.bat
Erro de entrada: Não há mecanismo de script para a extensão de arquivo ".js".
Now run 'configure --help'

c:php-devphp-5.4.4>cscript/nologo configure.js
Erro de entrada: Não há mecanismo de script para a extensão de arquivo ".js".

Estou desenvolvendo este trabalho Windows 7 64 bits, acho que este é um problema comum da versão, para resolver veja este tutorial (em inglês), bem simples, é só seguir os passos. Após seguir os passos do tutorial, tente executar os scripts novamente.

Caso tudo der certo você terá uma tela semelhante a da figura abaixo. Após o último comando o script configure vai gerar uma resposta enorme, a imagem abaixo contém apenas o começo dela.

Início do retorno após a execução do script configure.js

2. Configuração da IDE com o Código Fonte do PHP

Abra o Microsoft Visual Studio C++ 2008 Express Edition, crie um novo projeto Win32 (File -> New -> Project -> Win32 ->Win32 Project), dê um nome a ele, em nosso exemplo “php_first_extension”. Em seguida irá abrir uma janela: “Win32 Application Wizard – php_first_extension”, clique em “Next”. Na próxima tela do assistente você terá um grupo de opções denominado “Application Type“, selecione “DLL“. e por fim clique em “Finish”. Quando você terminar terá uma estrutura no “Solution Explorer” como na figura abaixo:

Solution Explorer – Microsoft Visual C++ 2008 Express Edition

Muito bem! Agora temos que configurar algumas diretivas nas propriedades projeto. Clique com  o botão direito sobre o nome do projeto (php_first_extension), e no fim da lista vá em “Properties“. Abrirá uma janela “php_frist_extension Property Pages”, e dentro dela você irá ver a sua esquerda vários itens filhos de “Configuration Priperties“, dentre os itens, os que vão nos interessar são: “General“, “C/C++” e “Linker“. Não vou entrar em detalhes sobre cada um, apenas altere as configurações de acordo com o que está sem seguida.

Entre no subitem “General“, altere as seguintes configurações:

  • “Character Set” para “Use Multi-byte Character Set”.
Em seguida, entre no subitem C/C++, em “General” e altere as seguintes diretivas:
  • “Debug Information Format” para “Program Database (/ZI)”.
  • “Detect 64-bit Portability Issues” para “No” (Se você estiver no Windows 64, como é no meu caso, esta opção já deve aparecer como “No”).
  • “Addition Include Directories”, neste campo você irá indicar onde os fontes do PHP estão, conforme você baixou e descompactou no Item 1 (“C:/php-dev/php-5.4.4″), após a configuração irá ficar desta maneira:
C:/php-dev/php-5.4.4/main 
C:/php-dev/php-5.4.4/Zend 
C:/php-dev/php-5.4.4/TSRM 
C:/php-dev/php-5.4.4/
.
Em seguida no subitem Preprocessor, adicione em Preprocessor Definitions:
ZEND_DEBUG=0    
ZTS=1    
ZEND_WIN32
PHP_WIN32
Feito isso, vamos para o subitem seguinte “Code Generation“, sete as configurações como está abaixo:
  • “Enable String Pooling” para “Yes (/GF)”.
  • “Enable Minimal Rebuild” para “No”.
  • “Basic Runtime Checks” para “Default”.
  • “Runtime Library” para “Multi-threaded Debung (/MTd)”.
.
No próximo item da lista, “Linker“, no primeiro subitem “General”, mude a seguinte configuração: “Adition Library Directories“, adicionando o caminho “C:/php/dev”, que é onde meu PHP está instalando e funcionando, veja não é o diretório dos fontes do PHP, se você olhar dentro deste diretório verá o arquivo “php5ts.lib“, que no subitem “Input”, procure pela propriedade “Addition Dependencies“, e coloque “php5ts.lib“.
.
Ok, até agora nenhuma tarefa complicada (apensar de muito extensa), já estamos com nossas ferramentas instaladas e configuras. No item seguinte vamos criar um pequeno exemplo.
.

3. Exemplo de Extensão e Configuração com o PHP

Agora que temos nosso projeto criado, e o ambiente de desenvolvimento configurado vamos criar um pequeno exemplo, e “junta-lo” com nosso PHP já instalado.

Primeiramente abra o arquivo de cabeçalho stdafx.h, que está em “Header Files”, apague todo seu conteúdo e coloque:

#ifdef PHP_WIN32
   #pragma once
   #include "zend_config.w32.h"
   #include "php.h"
#endif

Em seguida, abra o arquivo php_first_extension.cpp, apague todo seu conteúdo e coloque:

#include "stdafx.h"

PHP_FUNCTION(first_extension);

zend_function_entry php_fist_extension_functions[] = {
   PHP_FE(first_extension, NULL)
   {NULL, NULL, NULL}
};

PHP_MINIT_FUNCTION(php_first_extension)
{
   return SUCCESS;
}

PHP_MINFO_FUNCTION(php_first_extension)
{
}

zend_module_entry php_first_extension_module_entry = {
   STANDARD_MODULE_HEADER,
   "PHP First Extension do Blog do Tiago",
   php_fist_extension_functions,
   PHP_MINIT(php_first_extension),
   NULL, 
   NULL, 
   NULL, 
   PHP_MINFO(php_first_extension),
   "0.1", 
   STANDARD_MODULE_PROPERTIES
};

ZEND_GET_MODULE(php_first_extension)

PHP_FUNCTION(first_extension)
{
   char *strMensagemSucesso = "Parabéns! sua extensão está funcionando!";
   RETURN_STRING(strMensagemSucesso, 1);
}

Remova do projeto os outros arquivos, não vamos utiliza-los por enquanto. Quando ao código no próximo post explico mais profundamente sobre ele.

Bom, agora vamos construir nosso projeto. Mais uma vez com o botão direito sobre o nosso do nosso projeto, clique em Build, ele irá começar a compilar nosso código, que resultará em um arquivo chamado “php_first_extension.dll” que estará dentro da pasta “Debug” no caminho que você salvou o projeto no seu computador. Você verá uma mensagem parecida como esta na IDE:

1>------ Build started: Project: php_first_extension, Configuration: Debug Win32 ------
1>Linking...
1>   Creating library C:UsersTiagoDocumentsVisual Studio 2008Projectsphp_first_extensionDebugphp_first_extension.lib and object C:UsersTiagoDocumentsVisual Studio 2008Projectsphp_first_extensionDebugphp_first_extension.exp
1>Embedding manifest...
1>Build log was saved at "file://c:UsersTiagoDocumentsVisual Studio 2008Projectsphp_first_extensionphp_first_extensionDebugBuildLog.htm"
1>php_first_extension - 0 error(s), 0 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Para testar este exemplo de extensão, copie o arquivo “php_first_extension.dll” para o diretório “ext“, no meu caso “C:/php-5.4.4/ext”, em seguida abra o arquivo php.ini (que está um diretório acima), procure pelas linhas onde estão o “loading” das extenções, e então adicione:

extension=php_first_extesion.dll

Feche o arquivo php.ini salvando as alterações, restarte seu servidor web (se estiver utilizando o Apache, pode-se utilizar o “Apache System Monitor”).

Crie um arquivo PHP no diretório acessível do seu servidor, dê o nome que quiser, neste arquivo vamos chamar nossa extensão com o seguinte código:

<?php
    echo first_extension();
?>

Se tudo correr bem você verá a seguinte mensagem na tela: “Parabéns! sua extensão está funcionando!“. Se você criar um arquivo PHP com a função “php_info()”, nele você também irá notar os dados da sua extensão, vale a pena ver!

Se você quiser pode fazer o download dos arquivos do projeto aqui.

4. Conclusão da Segunda Parte

Nesta segunda parte fizemos o download das ferramentas necessárias para a construção de extensões no Microsoft Windows, instalamos e as configuramos, além de elaborar e “testar” um pequeno exemplo de extensão externa (dll). A tarefa foi simples, nos próximos posts vamos explorar um pouco da Zend API e elaborar projetos mais complexos.

Referencias

.

Abraços,

Tiago.

Publicado em C/C++, Extensões, PHP | Com a tag , , , | Deixar um comentário

Vídeo Aulas: Criando um Mini-Framework MVC com PHP

Olá amigos!

Esses dias eu estava navegando e encontrei algumas vídeo aulas do Mateus Moura, achei bem interessante a abordagem e a construção. Nestas que listei abaixo ele constrói do zero um framework MVC utilizando PHP. Apensar de se contra a construção de frameworks caseiros, acredito que quem nunca trabalhou dessa maneira,  ao ver essas vídeo aulas poderá entender melhor quando iniciar seu aprendizado, como por exemplo, da Zend Framework.

Listei as vídeo aulas abaixo com os respectivos assuntos, espero que seja útil.

  1. Parte I: Arquivo .htaccess, URL amigáveis e estrutura de diretórios.
  2. Parte II: Explorando os Models
  3. Parte III: Melhorando o Framework, tratamento de erros, captura de parâmetros na URL
  4. Parte IV: Helpers e início da construção de um exemplo
  5. Parte V: Construção de um Exemplo (boa exploração dos controllers e models)
  6. Parte VI: Exploração mais profunda dos Helpers
  7. Parte VII:Helpers, inicializadores, Login, Administração do Site
  8. Parte VIII: Explicações e esclarecimento de dúvidas (Complemento da Aula 7)
  9. Parte IX: Explicações gerais sobre os conceitos apresentados.

 

Abraços,

Tiago.

Publicado em PHP | Com a tag , , | Deixar um comentário

Criando Extensões para o PHP: Parte I – Introdução

Olá Leitores!

Hoje pretendo iniciar uma empreitada ao “submundo” do PHP, onde vamos explorar suas entranhas e tentar escrever uma extensão. Apesar desse tema parecer ir na contra-mão das tendencias (leia-se Frameworks), tem-se que em determinadas situações, isso para não dizer bem específicas, é necessário escrever suas funções diretamente em C/C++.

Já devo ter lido em algum lugar (não me lembro onde) que se caso você tenha uma função que seja muito usada, seria melhor escreve-la em C. Provavelmente a motivação de quem escreveu (e também a minha) é o ganho computacional que se tem, uma vez que o os códigos C/C++ são muito mais rápidos em comparação com os escritos em PHP.

Antes de iniciar a pesquisa para este post eu me deparei com uma dificuldade em especial: Falta de material de referencia, quando não ausente, está desatualizado. No manual do PHP que fala sobre este tema encontra-se algo, mas referente ao PHP 4, de acordo com uma viso logo no início. Mas como estamos apenas fazendo um experimento, vamos trabalhar com oque temos e no decorrer da série de posts, veremos o que acontece.

Antes de mais nada, consideremos alguns fatores como premissas:

  • A abordagem será direta, dando o caminho das pedras do “como fazer”.
  • Compreender a fundo o funcionamento interno do PHP é difícil, então vamos nos ater ao que interessa.
  • O estudo pode ser árduo, então vamos praticar, tentar e retentar. A palavra chave vai ser transpiração.
  • Você deve conhecer um pouco de C/C++? Mais a frente ele será necessário. Pretendo escrever sobre este assunto aqui no blog, em paralelo.

Para contextualizar e entender o que estamos nos propondo a fazer vamos dar uma olhadas nas possibilidades que temos, dada a arquitetura de funcionamento do PHP. Os itens adiante descrevem de acordo com o manual oficial as possibilidades de extensão da linguagem e alguns casos que já foram implementados.

1. PHP, o que é e como Funciona

O PHP é descrito como uma linguagem, e é por definição uma linguagem interpretada, e assim ela possui um interpretador, denominado Zend Engine, que é uma espécie de máquina virtual, assim como no Java (só que mais rápido). Sendo que um dos motivos que popularizou o PHP é justamente a capacidade de estender o seu interpretador! A função do interpretador (que também iremos chamar de núcleo ou core) é ler o código fonte e “traduzi-lo” em código executável – linguagem de máquina. O núcleo do PHP está escrito em C, e para estende-lo iremos utilizar o C++ (poderíamos utilizar o C, mas por razões que você verá durante a série será mais conveniente utilizar C++).

Bom, agora sabemos que o PHP possui um núcleo chamado Zend Engine que é responsável por compilar e executar nossos scripts, só que o PHP em si é um pouco maior do que isso (bem maior na verdade), e está divido em três partes:

  • Interprete: Zend Engine, que faz o trabalho que descrevemos acima, se você quiser se aprofundar veja aqui e aqui.
  • Funcionalidade: implementa as funções da linguagem, as que você já deve conhecer.
  • Interface: Faz a interface com o servidor Web (e. g. Apache).

Na figura abaixo temos a a exemplificação da arquitetura do PHP, juntando os itens que citamos anteriormente:

Arquitetura Interna de Funcionamento do PHP
Fonte: Manual do PHP

Na figura você pode notar que todo acesso a banco de dados é feito pelos módulos, que são extensões do núcleo, e onde justamente nossa extensão vai estar. Ainda observando a figura tem-se o trajeto de ida e volta no paradigma cliente-servidor, onde a aplicação é solicitada no servidor web (1), por meio da interface (2) o Zend Engine é chamado, e em seguida irá buscar o script no disco do servidor (3), que será compilado e executado (4), nesse meio tempo o interpretador poderá acessar um dado módulo que é chamado no script, e após será compilado e executado (4). A resposta é enviada de volta a interface do servidor (5), que por sua vez enviará de volta ao navegador (6).

Agora sabemos que nosso ambiente de trabalho poderá estar em três seções, vejamos então quais são as possibilidades.

1.1 Extensões Externas

As funções externas são aquelas que pode ser carregadas externamente pela função dl(), tem-se que estes são casos muito específicos, pois dadas as desvantagens deste método o ganho de desempenho proposto no início do post não faz sentido, uma vez que estes carregamentos demandam muita memória (e tempo!). Dê uma olhada na tabela abaixo retirada do manual do PHP:

Vantagens Desvantagens
Os módulos externos não necessitam que você recompile o PHP. É necessário carregar a extensão todas as vezes que for usa-la.
O tamanho do PHP não é alterado. É necessário fazer acesso ao disco (o que é muito lento) toda vez que o módulo for requisitado.

O manual ainda cita que este é um método que pode ser usado caso você esteja em um ambiente compartilhado, o que é mais comum na maioria dos casos, pois não há possibilidade de recompilar o PHP com a extensão, ou modificar alguma diretiva no arquivo php.ini.

1.2 Build-in Modules

Como você já deve ter percebido esta é a abordagem que nos interessa: vamos desenvolver um módulo e compila-lo junto com o PHP, acredito que seja neste contexto que teremos o ganho de desempenho mais considerável. Uma das reflexões que podemos ter nesta abordagem é: Posso ter minha aplicação totalmente feita e compilada junto com PHP? Separei dois itens abaixo onde temos um parenteses sobre esta reflexão e outra que irá complementar o item 1.3, estes subitens não estão muito direcionados na nossa empreitada, no entanto que vale a pena ler.

Abaixo tem-se a tabela com as vantagens e desvantagens dessa abordagem, o conteúdo também foi adaptado do manual do PHP.

Vantagens Desvantagens
Não é necessário carregar explicitamente o módulo, ele apresenta-se como uma funcionalidade nativa do PHP. Necessita de recompilar o PHP.
Não existem arquivos externos a serem carregados. Tudo já está compilado junto com o PHP. O PHP cresce e consumirá mais memória.

Uma das desvantagens citadas é o aumento no consumo de memória. Não podemos esquecer que a boa programação do nosso módulo vai minimizar este efeito, e que seus malefícios também poderiam ser percebidos se a nossa extensão fosse implementada em código PHP; pense como exemplo a manipulação de imagens, no decorrer da nossa aboragem vamos analisar, como estudo de caso, o material do post do Francismo de Souza Júnior, onde ele desenvolve uma extensão para detecção de objetos utilizando a biblioteca OpenCV.

Uma das considerações mais obvias que temos é que nesta abordagem é necessário que, caso pretenda utilizar seu módulo como nativo no PHP, você tem há de dispor de um servidor onde possa modificar o PHP a seu gosto, como uma hospedagem dedicada, dado que vamos recompilar o PHP.

1.2.1 Algumas palavras sobre as modificações do Facebook, o HipHop

Em fevereiro de 2010 a equipe de desenvolvimento do PHP postou em seu blog uma novidade, o denomindado HipHop, que na verdade não é uma extensão, mas sim um PHP totalmente modificado, onde inicialmente tinha-se que ele realiza a transformação do código PHP em para C++, que por sua vez era compilado pelo g++. Dê uma olhada na figura abaixo para observar o processo:

Transformação de código PHP em executável.
Fonte: Br-Linux

De acordo com o post, a preocupação inicial era com o desempenho (consumo de CPU) das linguagens interpretadas frente as compiladas. No decorrer da narrativa o autor cita o desenvolvimento de extensões e argumenta que dado o tamanho da equipe e a complexidade que envolvia o desenvolvimento das tais extensões, transcrever as regras de negócio do Facebook inicialente escritas em PHP para código C++ seria um trabalho demasiado custoso, tendo em vista os aspectos como o conhecimento de C++ e da Zend API (nos aprofundaremos neste tópico nos próximos posts), por fim é citado que obteve-se um ganho de 50% na execução da aplicação.

Este é um assunto que cabe um post mais específico para investigar o assunto, pretendo em breve escrever algo sobre.

1.2.2 “Compilando” meu código PHP

De maneira mais simplória do que no HipHop, durante a pequisa para iniciar este post encontrei um post muito interessante no blog do Rafael Clares, que tratava a compilação de classes escritas em PHP em códigos C++ utilizando o módulo nativo do PHP, o bcompiler. Se você pensa em justamente compilar toda sua aplicação, creio que  leitura do Rafael seja mais adequada.

1.3 Modificações no Zend Engine

Nossa terceira e ultima abordagem trata-se da modificação do Zend Engine. Como vimos o núcleo do PHP é responsável por compilar e executar o script em tempo de execução, então pode-se inferir que a modificação do interpretador apenas se justifica quando é necessário modificar o comportamento da linguagem. No manual é evidente que tais modificações não são recomendadas, pois resultariam em incompatibilidades e dada a característica da modificação, aumenta-se o acoplamento da aplicação (o que é um fator indesejado), e para dificultar ainda mais a implementação da extensão, não existe abordagem oficial no manual do PHP para tal. Lembrando que assim como no item 1.2 é necessário recompilar o PHP.

2. Conclusão da Primeira Parte

Bom amigos, chegamos a conclusão da primeira parte do nosso trabalho, agora já sabemos quais são as possibilidades para escrever extensões e citamos alguns exemplos de trabalhos parecidos. No próximo post vamos explorar a anatomia da extensão e configurar o ambiente de desenvolvimento, ainda não decidi se iremos explorar no Linux ou no Windows, estou inclinado a seguir no Windows porque notei alguns trabalhos já explorando o desenvolvimento no Linux, então algo novo seria mais apropriado.

Estou aberto a sugestões, críticas, elogios e qualquer outro tipo de contato! Até o próximo post!

3. Referencias

Abraços,

Tiago.

Publicado em C/C++, Extensões, PHP | Com a tag , , , | Deixar um comentário

Instalando o Apache 2.4.2 com o PHP 5.4.4 no Windows 7 64 bits

Olá Amigos!

Este é o tipo de post clássico que todo blog sobre PHP deve ter. Anteriormente eu já havia mencionado aqui as novas funcionalidades do PHP 5.4, então chegou a hora de realizarmos a instalação. Como dito no título estamos realizando a instalação no ambiente Windows de 64 bits.

1) Faça os Downloads:

.

2) Instalação e Configuração do Apache

Feito o download copie o arquivo “httpd-2.4.2-win32.zip” para o “C:” e extraia o arquivo, ficando o diretório “Apache24″. Entre no diretório e procure o arquivo “httpd.conf” dentro do diretório “conf”, adicione as seguintes linhas no final do arquivo:

# Add to your httpd.conf
LoadModule php5_module "c:/php/php5apache2_4.dll"
AddHandler application/x-httpd-php .php

# configure the path to php.ini
PHPIniDir "C:/php"

Neste trecho estamos dizendo para o Apache “conversar” com o PHP, via a extensão “php5apache2_4.dll” que você baixou anteriormente (mais a frente vamos ver como proceder com a instalação da extensão).

Agora vamos definir o ServerName, dica: dê um CTRL + F e procure por “ServerName”, encontrando-o atribua o valor: “localhost:80″

Bom, não podemos nos esquecer que precisamos fazer com que nosso Apache “abra” os arquivos “.php”, para tal procure pelo trecho de código abaixo, nele já consta a modificação com o “index.php”, assim “abriremos” os arquivos no navegador.

<IfModule dir_module>
    DirectoryIndex index.html index.php index.phtml
</IfModule>

Ok, quase tudo pronto, agora vamos definir onde nossos arquivos PHP estão, procure pela linha:

DocumentRoot "c:/Apache24/htdocs"
<Directory "c:/Apache24/htdocs">

Altere conforme a localização dos arquivos e atenção: se você colocar um caminho que não existe o Apache não irá startar!

Pronto, as etapas de configuração do Apache terminaram, vamos adiciona-lo agora como um serviço do Windows. Abra o Prompt de Comando e digite:

c:apache24binhttpd -k install

Para inicia-lo automaticamente, entre no gerenciador de serviços do Windows (menu Executar, “services.msc”), lá você pode setar para o serviço iniciar automaticamente.

3) Instalação e Configuração do PHP

Esta é a parte mais fácil, após o donwload copie o arquivo “php-5.4.4-Win32-VC9-x86.zip” para seu “C:”, descompacte e renomeie o diretório para “php”. Feito isso dentro do arquivo “php5apache2_4.dll-php-5.4-win32″ você irá encontrar um diretório chamado “PHP 5.4.4″ e dentro dele uma DLL “php5apache2_4.dll”, pois bem, copie-a para a pasta raiz do PHP: “C:/php”, assim como eu disse acima, o PHP irá conversar com o Apache.

Em seguida temos que editar o arquivo de configuração do PHP, renomeie o arquivo “php.ini-development” para “php.ini”, e abra-o:

3.1) Procure pela linha “extension_dir” e descomente-a (a que faz referencia ao ambiente Windows) e atribua o valor: “C:/php/ext”

3.2) Role o arquivo até encontrar a lista de extenções, como esta:

; Windows Extensions
; Note that ODBC support is built in, so no dll is needed for it.
; Note that many DLL files are located in the extensions/ (PHP 4) ext/ (PHP 5)
; extension folders as well as the separate PECL DLL download (PHP 5).
; Be sure to appropriately set the extension_dir directive.
;
;extension=php_bz2.dll
extension=php_curl.dll
;extension=php_fileinfo.dll
extension=php_gd2.dll
;extension=php_gettext.dll
;extension=php_gmp.dll
;extension=php_intl.dll
;extension=php_imap.dll
;extension=php_interbase.dll
;extension=php_ldap.dll
extension=php_mbstring.dll
extension=php_exif.dll      ; Must be after mbstring as it depends on it
extension=php_mysql.dll
;extension=php_mysqli.dll
;extension=php_oci8.dll      ; Use with Oracle 10gR2 Instant Client
;extension=php_oci8_11g.dll  ; Use with Oracle 11gR2 Instant Client
;extension=php_openssl.dll
;extension=php_pdo_firebird.dll
extension=php_pdo_mysql.dll
extension=php_pdo_oci.dll
extension=php_pdo_odbc.dll
extension=php_pdo_pgsql.dll
;extension=php_pdo_sqlite.dll
extension=php_pgsql.dll
;extension=php_pspell.dll
;extension=php_shmop.dll

Descomente as que você for usar (removendo o “;” do início da linha). Repare que eu já descomentei algumas que uso.

Feche o arquivo e salvando as configurações. E dê um restart no Apache, com este código no Prompt de Comando:

httpd -k restart

Se tudo deu certo você não receberá nenhuma mensagem de erro, siga para o próximo item.

4) Testando nossa instalação

Acesse o diretório que você atribui nas configurações do Apache como diretório que estão seus arquivos PHP. Crie um arquivo.php, abra-o e coloque o código:

<?php

phpinfo();

?>

Salve e Feche-o. Após acesse: http://localhost/arquivo.php

Se tudo ocorrer bem você verá uma página contendo todas as configurações do PHP e os módulos instalados.

É isso pessoal!

Abraços,

Tiago.

Publicado em PHP | Com a tag , , | Deixar um comentário

PostgreSQL: Funções que retornam conjuntos de registros

Olá mentes ávidas do amanhã!

Algumas vezes eu me deparei com o problema de retornar mais de um resultado com uma função, um conjunto de resultados, e o Postgres nos favorece com alguns artifícios para tal. De fato não são exatamente muito simples de se manejar, mas também não é um bicho de sete cabeças. Tal como fizemos quando manipulamos triggers, aqui iremos utilizar a linguagem PL/pgSQL para construirmos nosso trabalho, que consistirá em quatro maneiras. Outra informação importante é que enquanto eu escrevia esse post estava usando a versão 8.3 para realizar os testes nos códigos.

 

Eu encontrei duas  maneiras de executar esse trabalho, e após compartilhar o post no grupo PostgreSQL  Brasil no LinkedIn, o Fabrízio que orientou mais duas maneiras que veremos a seguir, e se você souber de mais alguma sinta-se livre para contribuir, por exemplo, enquanto eu estava escrevendo a primeira versão minha doce namorada Bruna me deu várias luzes. Bom mas abordando o nosso tema, inicialmente tomemos vejamos as seguintes linhas de código que representam a tabela que será a base das nossas consultas:

CREATE TABLE pessoa_fisica (
	id_pessoa SERIAL,
	nome VARCHAR(80),
	sobrenome VARCHAR(200),
	sexo CHAR(1),
	cpf CHAR(11),
	PRIMARY KEY(id_pessoa)
);

Agora vamos aos métodos de retorno dos dados que estão dentro desta tabela (presumo que você tenha abastecido ela), como mencionei vou abordar quatro maneiras.

1) Tipo retorno RECORD

Um tipo “genérico”, bem mais comum nas buscas na internet, este é o tipo mais comentado, mas existe um empecilho, o qual é necessário especificar as colunas que iremos resgatar quando chamarmos a função, veja o código abaixo na linha 8:

CREATE FUNCTION blog_get_pessoas() RETURNS SETOF RECORD AS $$
BEGIN
	RETURN QUERY SELECT id_pessoa, nome, sobrenome, sexo, cpf FROM pessoa_fisica;
	RETURN;
END;
$$ LANGUAGE 'plpgsql';

SELECT * FROM blog_get_pessoas() AS (id_pessoa INTEGER, nome VARCHAR, sobrenome VARCHAR, sexo CHAR, cpf CHAR)

Veja que quando defini o tipo de retorno da função eu determinei dois parâmetros, SETOF que indica que a função irá retornar um conjunto de itens, ao invés de um único item e RECORD que está me dizendo que o retorno será um conjunto de resultados. Perceba que utilizei a instrução RETURN QUERY e logo após um SELECT tradicional para “capturar” os dados, o RETURN QUERY foi introduzido no Postgres na versão 8.3.

Observe que a instrução RETURN (sozinha, na linha 4) é que irá realizar o retorno do nosso conjunto. Agora note a forma estranha que chamamos a função, como se fosse uma tabela realizamos o select e em seguida empreendemos um “alias” especificando quais campos vieram na query realizada (estranho, não?), enfim se você não colocar todos os campos, conforme a query que foi realizada na função, haverá problemas.

2) Retornando os campos de uma dada Tabela

Agora se os dados de retorno da sua função forem oriundos de apenas uma tabela, você pode setar o tipo de retorno como sendo exatamente o da tabela trabalhada, veja que no nosso exemplo que coloquei pessoa_fisica, como o tipo de retorno:

CREATE FUNCTION blog_get_pessoas2() RETURNS SETOF pessoa_fisica AS $$
BEGIN
	RETURN QUERY SELECT * FROM pessoa_fisica
	RETURN;
END;
$$ LANGUAGE 'plpgsql'

SELECT * FROM blog_get_pessoas2();

Aqui temos como retorno possível todos os campos da nossa tabela de teste, no caso pessoa_fisica, claro que ao chamar a função você poderia selecionar os campos que vão lhe interessar. Repare que ao contrário do primeiro exemplo não precisamos especificar quais campos eventualmente viriam na query, essa na minha opinião é uma das maneiras mais práticas, mas ai vai da sua necessidade.

3) Tipo de retorno RETUNS TABLE

Apensar de eu não conseguir testar o RETURNS TABLE (porque a versão 8.3 ainda não suportava esse recurso) ela existe, veja aqui na documentação oficial do Postgres. Dê uma olhada de como ficaria o código da nossa função:

CREATE FUNCTION blog_get_pessoas3() RETURNS TABLE (id_pessoa INT,
						   nome VARCHAR,
						   sobrenome VARCHAR,
						   sexo CHAR,
						   cpf CHAR) AS $$
BEGIN
	RETURN QUERY SELECT * FROM pessoa_fisica;
	RETURN;
END;
$$ LANGUAGE 'plpgsql'

SELECT * FROM blog_get_pessoas3();

Repare que declaramos os atributos, que serão os “nomes de coluna” quando chamarmos nossa função. É muito útil quando vamos retornar dados de mais de uma tabela, ao contrário de tudo que já vimos anteriormente, dessa maneira podemos expressar no corpo da função, explicitamente, quais serão as tuplas no retorno. Uma observação importante: repare que na linha 7 eu estou selecionando todos os campos, você deve atentar-se para que todos os campos coincidam com os determinados no tipo de retorno.

4) Criando um tipo específico de retorno, o CREATE TYPE

Já a quarta opção, é que criamos o tipo de retorno da função “personalizado”, exatamente como nesta instrução:

CREATE TYPE type_pessoa_fisica AS (
	id_pessoa INT,
	nome VARCHAR,
	sobrenome VARCHAR,
	sexo CHAR,
	cpf CHAR
);

Repare que a instrução CREATE TYPE é bem semelhante a instrução para criação de tabelas, com ela é possivel criar um “mix” de duas tabelas por exemplo, ai vai da sua imaginação, aqui no meu exemplo ficou bem simples, mas agora que vem a parte interessante, veja como ficou a nossa função:

CREATE FUNCTION blog_get_pessoas4() RETURNS SETOF type_pessoa_fisica AS $$
DECLARE
	dados_pessoa type_pessoa_fisica;
BEGIN
	FOR dados_pessoa IN SELECT id_pessoa, nome, sobrenome, sexo, cpf  FROM pessoa_fisica LOOP
		RETURN NEXT dados_pessoa;
	END LOOP;
	RETURN;
END;
$$ LANGUAGE 'plpgsql'

SELECT * FROM blog_get_pessoas4();

A primeira coisa que notamos a ler é o tipo de retorno da função, o type_pessoa_fisica que já especifica quais os campos que serão retornados, posteriormente temos o DECLARE onde construimos uma variável chamada dados_pessoa que irá conter o conteudo da nossa query, note que tem o mesmo tipo de retorno da função, exatamente porque é esta variável que vamos retornar. Em seguida, para abastecer a nossa variável com os registros da tabela temos a instrução FOR-IN-SELECT que é m looping que a cada iteração “coloca uma linha na variável”, repare que a instrução RETURN NEXT é que “abastece” nossa variável, e apesar de ser um “RETURN” não encerra a execução do código naquele instante, note que há a instrução RETURN após o fim do loop (END LOOP), esta sim irá terminar a função.

E na linha 12 temos a chamada da função, bem mais amigável que em comparação com o experimento 1, e é (quase) exatamente como a chamada de uma tabela, lá você pode introduzir as clausulas WHERE e LIMIT por exemplo.

Espero que tenham gostado! Façam os testes e não deixem de comentar, e conheça também a fã page do blog no Facebook.

Referências:

Abraços,

Tiago.

Publicado em PostgreSQL | Com a tag | Deixar um comentário

Conhecendo o operador Similar To no PostgreSQL

Olá Amigos!

Prazer em revê-los novamente aqui no blog, e inicialmente eu gostaria de agradecer a audiência que vem crescendo a cada mês! Já estamos indo para 7 meses de blog e meus posts sobre o PostgreSQL estão sendo bem recebidos pela comunidade! Meu muito obrigado a vocês que fazem o blog acontecer!

Tratando agora do nosso assunto, em um post anterior sobre a utilização do operador iLIKE eu mencionei a particularidade do Postgres em realizar buscas discernindo os caracteres upper-case de low-case, no entanto há também a possibilidade de inserir expressões regulares a fim de refinar a busca, e para tal utilizamos o operador Similar To.

Para ilustrar o funcionamento desse operador, tome como base este problema: “Recuperar o nome das pessoas que terminam em “Silva” ou “Souza”. Aqui vocês irão me dizer que poderíamos utilizar os operados que já conhecemos como o LIKE e o iLIKE, e claro que sim, poderíamos e inclusive eu fiz algumas comparações com o desempenho, veja só:

SELECT * FROM pessoas WHERE sobrenome LIKE '%SILVA' OR sobrenome LIKE '%SOUZA' -- Gastou 150 ms com 1961 resultados
SELECT * FROM pessoas WHERE sobrenome iLIKE '%silva' OR sobrenome iLIKE '%souza' -- Gastou 250 ms com 1961 resultados
SELECT * FROM pessoas WHERE sobrenome SIMILAR TO '(%SILVA|%SOUZA)' -- Gastou 350 ms com 1961 resultados
SELECT * FROM pessoas WHERE sobrenome SIMILAR TO '%(SILVA|SOUZA)' -- Gastou 300 ms com 1961 resultados

Pelo menos aqui nos meus testes o Similar To se mostrou o operador mais lento, apesar de não existir nenhuma referência sobre o desempenho dele no manual. Por natureza isso se deve acontecer porque ele mescla o funcionamento dos outros operadores testados com a implementação e expressões regulares POSIX. Eu não encontrei uma maneira de fazer o Similar To funcionar como o iLIKE, então se alguém tiver alguma sugestão sinta-se livre para comentar =)

Listei aqui abaixo os artivicios que você utlilizar para realizar junto com o Similar To como está no manual do Postgres:

  • | representa alternância (uma das duas alternativas).
  • * representa a repetição do item anterior zero ou mais vezes.
  • + representa a repetição do item anterior uma ou mais vezes.
  • Os parênteses () podem ser utilizados para agrupar itens em um único item lógico.
  • A expressão de colchetes […] especifica uma classe de caracteres, do mesmo modo que na expressão regular POSIX.

Seria muito interessante você dar uma lida no Manual do Postgres, lá você irá encontrar material mais completo, nas referências abaixo você tem o link que está em inglês, se preferir aqui está a versão em português, só que da versão 8.0 (apensar da versão em inglês não mudar muita coisa).

Referências:

Abraços,

Tiago.

Publicado em PostgreSQL | Com a tag | Deixar um comentário

PHP 5.4 liberado! Novas funcionalidades e facilidades!

Olá meus caros leitores!

Acho que vocês já estão acostumados com a minha ausência aqui então vamos ao que interessa! Ontem (01/03) foi liberado o PHP 5.4 e hoje estou aqui para comentar um pouco das novas funcionalidades, como a nova maneira de declarar um array, traits e um console para rodar códigos PHP diretamente!

Novidades nos Arrays

Quem geralmente trabalha com JavaScript estava acostumado a uma declaração mais curta, usando os [], assim eu peguei emprestado um exemplo do manual do PHP, dê uma olhada como é possível declarar arrays agora:

<?php

// Antes tinha que ser assim:
$array = array(
    "foo" => "bar",
    "bar" => "foo"
);

// Agora pode ser assim também!
$array = [
    "foo" => "bar",
    "bar" => "foo"
];
?>

E além da nova forma de declaração também foi implementado a Array Deferencing que em outras palavras é o acesso direito de um membro do array diretamente no retorno de um método/função caso este retorne um array:

<?php
function getArray() {
    return array(1, 2, 3);
}

// Como podemos fazer agora
$secondElement = getArray()[1];

// Como fazíamos "antigamente"
$tmp = getArray();
$secondElement = $tmp[1];

// ou assim
list(, $secondElement) = getArray();
?>

Bacana não é? isso vai deixar o código mais limpo e a programação mais divertida (saudades do meu tempo de programação PHP hehe).

 

Traits

E agora para deixar mais interessante, na versão 5.4 o PHP passa a implementar Traits, que aparecem para suprir aquelas problemas que você acredita  que seriam possíveis de resolver com herança múltipla no PHP, o que os Traits fazem é uma herança horizontal, sugiro que você dê uma lida no post do Hélio sobre isso, lá ele explicou de maneira muito proveitosa. Em todo caso abaixo você vê um exemplo da implementação deles no PHP, o exemplo foi tirado do Manual do PHP:

<?php
class Base {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait SayWorld {
    public function sayHello() {
        parent::sayHello();
        echo 'World!';
    }
}

class MyHelloWorld extends Base {
    use SayWorld;
}

$o = new MyHelloWorld();
$o->sayHello(); // Exibirá "Hello World"
?>

 

Build-in Web Server 

Agora o PHP implementa nativamente no seu núcleo um web server que você pode acessar via linha de comando no Linux, Windows e Mac. Dê uma olhada na documentação oficial dele aqui.

 

Melhorias Acrescentadas

 

Funcionalidades Removidas

  • Register_globals, safe_mode e magic_quotes removidos.
  • y2k_compliance no arquivo ini
  • Funções de sessão: session_is_registered(), session_register() e session_unregister()
  • Extensão do sqlite agora está no PECL

Bugs Resolvidos

  • #60879 unserialize() não chama  __wakeup() do objeto).
  • Correção da incompatibilidade de binários com PDO
  •  #48877  “bindValue” e “bindParam” agora funcionam para o PDO Firebird
  • #55801 Comportamento de unserialize() mudou para melhorar performance

Se você quiser ver toda a lista de novas funcionalidades e bugs resolvidos, olhe neste link.

Bom gente, esse foi meu simples review sobre os novos atributos da nossa querida linguagem, espero que vocês tenham gostado, e deem uma olhada na página oficial do PHP, lá vocês poderão encontrar informações e muitos mais exemplos no manual da linguagem.

 

Referências:

Abraços,

Tiago.

Publicado em PHP | Com a tag | Deixar um comentário

Calculando previsão de vendas com PHP e PostgreSQL

Olá Amigos!

Hoje eu vou tratar de um assunto da época da faculdade, o cálculo da previsão de vendas de um determinado produto, com base nas vendas anteriores, para tal iremos utilizar o PostgreSQL e PHP.

Mas antes de mais nada, estou disponibilizando um documento do Excel com os mesmos dados da figura abaixo, juntamente com um gráfico contendo os resultados e informações importantes como o valor do r² e a equação do nosso modelo. Também achei importante disponibilizar os slides utilizados pelo Prof. Darlan quando este assunto foi ministrado, lá você irá encontrar mais conteúdo e uma bagagem teórica solida e enxuta.

Primeiramente vamos ao nosso problema:

Quanto eu devo investir em publicidade para ter um determinado ganho em vendas?

Quando nós chegarmos ao ponto de extrair os dados do Postgres perceberemos que na modelagem do banco estes dados (investimento e vendas) não tem nenhuma correlação, veja bem, do ponto de vista da modelagem. Por isso é muito importante que você compreenda bem nosso problema, e para simplificar na tabela abaixo temos os investimentos (ou gastos) com publicidade representado pela variável x, e as vendas representadas pela variável y. Note que além desses dados temos outros como , e xy, que iremos utilizar posteriormente.

Veremos estes mesmos dados a seguir quando estivermos trabalhando no banco de dados, coloquei a tabela de ante-mão para abstrair melhor nosso trabalho, e  na seção seguinte do post iremos abordar os conceitos matemáticos envolvidos e os nomes das colunas (as variáveis) irão aparecer nas fórmulas, e como já vimos estruturadamente, ficará mais fácil.

O objetivo então é que possamos construir uma aplicação que nos informe qual será o valor que iremos vender, baseando-se no valor que iremos investir em publicidade.

Ahh, antes que os mais críticos se envolvam, gostaria de dizer que este é um exemplo simples, se você quiser pode melhora-lo de acordo com a sua necessidade ;)

A matemática por traz do cálculo

Antes que muitos torçam o nariz ou pulem essa parte, já vou adiantando que nossa matemática será breve e simples. É fundamental que você entenda essas fórmulas (além de ler os slides que falei acima) para entender como funciona o nosso modelo.

E por falar em modelo, aqui temos um estatístico probabilístico, de regressão linear simples. Veja a representação do nosso modelo de equação abaixo:

Aqui temos que a variável y é explicada pela variável x, que por sua vez é explicativa. Então veja que, se estamos representando os gastos com publicidade por x, e as vendas por y, temos que os gastos com publicidade é que vão determinar o valor das vendas.

Note também que temos dois coeficientes, chamados de a e b. As duas fórmulas a seguir irão utilizar os nossos dados que estão na tabela (conforme a figura da primeira seção), que na  verdade iremos regastar do Postgres. Veja que abaixo temos a representação da fórmula onde iremos encontrar o valor de a:


Você deve ter percebido que para calcular o valor de a, antes é necessário obter o valor de b, pois bem, abaixo está a fórmula para o cálculo, veja um detalhe importante: o valor de n é exatamente o número de linhas da nossa tabela (ou o número de registros no banco de dados).

Agora que você já tem as duas fórmulas poderá chegar na equeção linear do nosso modelo, que será parecida com esta:

 y = 2,0754 + 2,0884.x

Como saber se o modelo é confiável?

Para sabermos se o nosso modelo é confiável contaremos com o Coeficiente de Correlação de Person, ou o famoso . Podemos calcular o valor do nosso coeficiente com a singela fórmula abaixo:

O resultado de r², irá variar entre -1 e 1, de forma que dependendo da variação, ela terá estes significados:

  • r² = -1 : Existe uma correlação inversa entra as variáveis, ou seja, quando uma aumenta a outra diminui.
  • r² = 0 : Modelo ruim, quanto mais próximo de 0, menos acertivo será seu modelo.
  • r² = 1 : Significa que seu modelo é muito bom! Ou seja, quanto mais próximo de 1, melhor!

No nosso exemplo, r² é de aproximadamente 0,93 e observe que ele está bem próximo de 1, o que nos indica que nosso modelo é consistente.

Construção das tabelas, queries, e dados no PostgreSQL

Este é o ponto mais importante do trabalho, aqui é onde iremos armazenar os dados que servirão de base para construírmos o modelo estatístico de previsão, para isso tome como base as duas tabelas a seguir conforme o modelo mostrado anteriormente:

CREATE TABLE investimento_publicidade (
	cod_investimento SERIAL,
	valor_investimento DOUBLE PRECISION NOT NULL,
	data_realizacao TIMESTAMP NOT NULL DEFAULT NOW(),
	PRIMARY KEY (cod_investimento)
);
CREATE TABLE vendas (
	id_produto SERIAL,
	nome VARCHAR(100) NOT NULL,
	preco_unitario DOUBLE PRECISION NOT NULL,
	quantidade_vendida INTEGER NOT NULL,
	PRIMARY KEY (id_produto)
);

Agora iremos abastacer o nosso modelo com os mesmos dados que utilizamos acima. Para agilizar e para podermos testar depois, disponibilizei o script SQL com as instruções INSERT abaixo:

INSERT INTO investimento_publicidade (valor_investimento) VALUES (3);
INSERT INTO investimento_publicidade (valor_investimento) VALUES (4);
INSERT INTO investimento_publicidade (valor_investimento) VALUES (8);
INSERT INTO investimento_publicidade (valor_investimento) VALUES (12);
INSERT INTO investimento_publicidade (valor_investimento) VALUES (14);

INSERT INTO vendas (nome, preco_unitario, quantidade_vendida) VALUES ('Produto A', 7 , 1);
INSERT INTO vendas (nome, preco_unitario, quantidade_vendida) VALUES ('Produto B', 14, 1);
INSERT INTO vendas (nome, preco_unitario, quantidade_vendida) VALUES ('Produto A', 15, 1);
INSERT INTO vendas (nome, preco_unitario, quantidade_vendida) VALUES ('Produto C', 28, 1);
INSERT INTO vendas (nome, preco_unitario, quantidade_vendida) VALUES ('Produto C', 32, 1);

Muito bem! Agora temos os nossos dados, e neste ponto vamos extaí-los do banco para elaborarmos a equação do nosso modelo de previsão com o PHP!

Então, considere as duas queries abaixo, primeiramente a query que nos retornará os valores investidos em publicidade:

SELECT SUM(valor_inestimento) AS x_somatoria_invest_publicidade, SUM(valor_inestimento^2) AS x_quadrado
FROM investimento_publicidade

Veja o que estamos retornando nesta query: a nossa variável x, que é a somatória dos valores investidos em publicidade e o , que iremos utilizar nas fórmulas.

E agora a query com os valores das vendas:

SELECT SUM((preco_unitario*quantidade_vendida)) AS y_somatoria_vendas, SUM((preco_unitario*quantidade_vendida)^2) AS y_quadrado
FROM vendas

Ok, temos retorno das variáveis y e y², repare que eu fiz umas brincadeirinhas, como a multiplicação do valor vendido pelo preço unitário, se você quiser pode brincar um pouco com os modelos depois alterando estes valores diretamente na tabela vendas.

NOTA: Eu poderia realizar toda a previsão de vendas somente dentro do Postgres, mas aqui quero utilizar o máximo de ferramentas possíveis, a previsão de vendas somente no PostgreSQL fica para um próximo post ok? =)

Exibição do modelo e simulação de dados com PHP

Veja abaixo o código de uma classe que irá realizar tanto os cálculos quanto as queries no Postgres, os comentários no código já explicam o que está acontecendo:

class PrevisaoVendas
{
	/**
	 * Atributo estático onde armazenaremos nosso objeto PDO para nossa comunicação com o banco de dados.
	 */
	private static $conn;

	/**
	 * Construtor da classe onde criamos e armazenamos nosso objeto PDO.
	 */
	public function __construct()
	{
		$opcoes_conexao = array(PDO::ATTR_ERRMODE    => PDO::ERRMODE_EXCEPTION, 
								PDO::ATTR_PERSISTENT => true);

		self::$conn = new PDO("pgsql:host=127.0.0.1 dbname=PREVISAO_VENDAS", "postgres", "senha", $opcoes_conexao);
	}

	/**
	 * Método responsável por retornar um objeto (stdClass) com os valores do x e x quadrado (investimento em publicidade)
	 */
	private function getValoresInvestimentosX()
	{
		$sql = "SELECT SUM(valor_inestimento) AS x_somatoria_invest_publicidade, SUM(valor_inestimento^2) AS x_quadrado "
		     . "FROM investimento_publicidade";

		$stmt = self::$conn->prepare($sql);
		$stmt->execute();

		return $stmt->fetchObject();
	}

	/**
	 * Método responsável por retornar um objeto (stdClass) com os valores do y e y quadrado (vendas)
	 */	
	private function getValoresVendasY()
	{
		$sql = "SELECT SUM((preco_unitario*quantidade_vendida)) AS y_somatoria_vendas, SUM((preco_unitario*quantidade_vendida)^2) AS y_quadrado "
			 . "FROM vendas";

		$stmt = self::$conn->prepare($sql);
		$stmt->execute();

		return $stmt->fetchObject();		
	}

	/**
	 * Método que calcula o valor de xy, a dica é você olha no manual do PHP as funções array_combine e array_sum
	 */
	private function getValorXY()
	{
		/**
		 * Obtendo os valores de x;
		 */ 	
		$stmt = self::$conn->prepare("SELECT valor_inestimento AS x FROM investimento_publicidade LIMIT 5");
		$stmt->execute();

		$x = array();

		while($rows = $stmt->fetchObject())
			$x[] = $rows->x;

		/**
		 * Obtendo os valores de y;
		 */ 
		$stmt = self::$conn->prepare("SELECT preco_unitario*quantidade_vendida AS y FROM vendas LIMIT 5");
		$stmt->execute();

		$y = array();

		while($rows = $stmt->fetchObject())
			$y[] = $rows->y;

		/**
		 * Calculando o valor da soma de xy
		 */ 
		$xy_aux = array_combine($x, $y);

		$xy = array();

		foreach($xy_aux as $key => $value)
			$xy[] = $key * $value;

		return array_sum($xy);			
	}

	/**
	 * Obtem o número de registros de vendas, o "n" utilizado nas equações, observe que o número de vendas poderá não ser igual ao número de
	 * investimentos, caberá a você criar um mecanismo para definir que sempre os dados analizados estarão na mesma proporção e consistentes,
	 * uma dica é a utilização de LIMIT e OFFSET.
	 */	
	private function getNumVendas()
	{
		$sql = "SELECT COUNT(*) FROM vendas";

		$stmt = self::$conn->prepare($sql);
		$stmt->execute();

		return $stmt->fetchColumn();		
	}

	/**
	 * Método onde estamos resolvendo a equação para encontrar o valor de "a".
	 */	
	private function getValorEquacaoA()
	{
		$x = $this->getValoresInvestimentosX();
		$y = $this->getValoresVendasY();
		$n = $this->getNumVendas();
		$b = $this->getValorEquacaoB();	

		$a = ($y->y_somatoria_vendas - ($b * $x->x_somatoria_invest_publicidade)) / $n;

		return $a;	
	}

	/**
	 * Método onde estamos resolvendo a equação para encontrar o valor de "b".
	 */	
	private function getValorEquacaoB()
	{
		$x  = $this->getValoresInvestimentosX();
		$y  = $this->getValoresVendasY();
		$n  = $this->getNumVendas();
		$xy = $this->getValorXY();		

		$b = (($n * $xy) - ($x->x_somatoria_invest_publicidade * $y->y_somatoria_vendas)) / (($n * $x->x_quadrado) - pow($x->x_somatoria_invest_publicidade, 2));

		return $b;		
	}

	/**
	 * Método para a identificação do valor de r quadrado, onde veremos que conforme o valor do índice teremos o nível de confiabilidade do modelo.
	 */	
	public function getValorRQuadrado()
	{
		$x  = $this->getValoresInvestimentosX();
		$y  = $this->getValoresVendasY();
		$n  = $this->getNumVendas();	
		$xy = $this->getValorXY();	

		$r = (($n * $xy) - ($x->x_somatoria_invest_publicidade * $y->y_somatoria_vendas)) / (sqrt(($n * $x->x_quadrado) - pow($x->x_somatoria_invest_publicidade, 2)) * sqrt(($n * $y->y_quadrado) - pow($y->y_somatoria_vendas, 2)));

		$r_quadrado = pow($r, 2);

		return $r_quadrado;		
	}

	/**
	 * Método para obteção de uma string contendo a fórmula do modelo.
	 */	
	public function getStringFormulaModeloPrevisor()
	{
		$a = $this->getValorEquacaoA();
		$b = $this->getValorEquacaoB();

		$string = "y = " . number_format($a, 4, ",", "") . " + " . number_format($b, 4, ",", "") . ".x";

		return $string;
	}

	/**
	 * Método que capta um dado valor em investimento de publicidade, e por meio do nosso modelo, retorna a previsão das vendas.
	 */	
	public function getValorSimuladoVendas($valor_invest_publicidade)
	{
		$a = $this->getValorEquacaoA();
		$b = $this->getValorEquacaoB();

		$y = $a + ($b * $valor_invest_publicidade);		

		return $y; // Nosso valor estimado das vendas.
	}
}

Veja um exemplo de utilização da classe:

$preview = new PrevisaoVendas();

$preview->getStringFormulaModeloPrevisor(); // Irá nos retornar a fórmula.
$preview->getValorRQuadrado();              // Valor do r quarado com a precisão do nosso modelo.
$preview->getValorSimuladoVendas(10.0);     // Retorna o valor das vendas, se no caso, invesrtirmos $ 10,00 em propaganda.

Então amigos, é isso ai, espero que vocês tenham gostado da simplória abordagem. Eu gostaria muito de saber das experiências de vocês, então fiquem a vontade para comentar!

Referências:

Abraços,

Tiago.

Publicado em PHP, PostgreSQL | Com a tag , , | Deixar um comentário