Há alguns dias me deparei com um  problema. Precisava conectar há servidores remotos via PHP, executar alguns comandos neles e tratar o resultado.
Para complicar um pouco mais, deveria ser possível conectar tanto via SSH quanto via Telnet.

Via SSH tudo bem, existe a library ssh2 do PHP que atende perfeitamente a este propósito, mas para Telnet, além de não haver nada nativo do PHP, encontrei uma grande deficiencia de materiais.

Resolvi então sair juntando o emaranhado de informações que encontrava na WEB e criar uma pequena library que atendesse aos dois protocolos, além de deixar em aberto a possibilidade de adicionar suporte a novos protocolos (porque não?).

A library está no github e segue o link https://github.com/tiagobutzke/php-remote-server.

Foi testada conectando via telnet e ssh há um servidor remoto Ubuntu e funcionou perfeitamente.
Não consegui ainda realizar o teste há um servidor Windows, mas quem quiser/puder testar e deixar seu feedback. Agradeço. 🙂


Fala pessoal, primeiramente vou me desculpar por ter passado tanto tempo sem postar nada. Mas foi por um bom motivo e esse bom motivo é o “porque” deste POST.

_ Vou falar sobre a Stoodos.
_ Stoodos? Mas o que é Stoodos? É um novo framework?

Não, não, não pessoal, stoodos é uma startup que esta lançando um produto voltado a educação a distancia em tempo real. Startup essa que eu estou fundando junto a meu sócio Frederico Blanco.

Explicando um pouco melhor como funciona tudo isso.
Muitas pessoas têm um bom conhecimento em várias áreas (PHP, Zend Framework, Origami..). Enfim, conhecimento esse que poderia ser compartilhado com outras pessoas na forma de cursos/treinamentos. Mas muitas vezes por conta de necessitar um alto investimento financeiro, espaço físico, tempo … Essas pessoas acabam guardando esse conhecimento para si.
A Stoodos pretende beneficiar essas pessoas, falta pouco para pormos no ar uma plataforma em que qualquer pessoa poderá facilmente criar um novo curso e qualquer pessoa poderá se matricular e assistir as aulas (isso tudo em tempo real, visando disponibilizar um ambiente o mais próximo possível de uma aula presencial).
E como nós vamos ganhar dinheiro? Dinheiro não é tudo nessa vida …  Então, se você criar uma turma gratuita nós não cobraremos nada de você. Esperamos apenas que você compartilhe seu conhecimento com um bom número de pessoas.
Ta certo, dinheiro não é tudo mas nós precisamos manter a Stoodos. Então caso você queira cobrar por um curso, nós gerenciaremos a transação financeira (aceitamos todos os cartões de créditos) e ficaremos com um pequeno (pequeno mesmo) percentual por aluno INSCRITO. Ou seja, você nunca sairá perdendo dinheiro! Legal não é mesmo?
Mas veja, nesse primeiro momento estaremos lançando apenas a parte gratuita da ferramenta.

Algumas funcionalidades iniciais da Stoodos:
– E-commerce de cursos;
– Stream da webcam/camera;
– Slide;
– Stream da tela de seu computador;
– Troca de materiais;
– Chat;
– Perguntas;
– Forte integração com redes sociais e muito enfoque em inovação;

Bom pessoal, é isso. Para quem se interessar estamos fazendo um cadastro de emails lá em www.stoodos.com, em breve, MUITO EM BREVE MESMO estará tudo ok  e nós notificaremos a todos os que fizerem o cadastro.

Hehe.. Só mais uma coisa, se for possível ou de sua vontade clica lá no botão de Tweet e Curtir (na home da stoodos) para nos dar uma força com a divulgação. Toda ajuda será bem vinda.

Valeu pessoal, é isso. Chega de jabá por hoje.
Assim que a Stoodos estiver no ar vou organizar um pouco mais as coisas e tentar fazer três POST’s por semana. E agora vou falar das minhas experiências empreendedoras também. 🙂

Grande abraço e fiquem com Deus.


Boa noite pessoal, pesso desculpas por meu sumiço do Blog mas ando bastante ocupado. Arrumei agora um tempo que não tenho pra vir aqui postar um artigo que achei, e traduzi pra vocês, enquanto estudava um pouco de nosql. O artigo fala sobre a instalação e utilização do MongoBD.

“MongoDB é a solução escalável, com alto desempenho, open source, schema-free, banco de dados orientado a documentos. Escrito em C++” – http://www.mongodb.org (mongodb.org)

Houve bastante publicidade sobre bancos de dados NOSQL nos últimos meses. CouchDB, Cassandra e Redis são conhecidos por serem altamente escaláveis e incrivelmente rápidos, porém a instalação e adoção por desenvolvedores amadores tem sido relativamente baixa por causa da necessidade de uma alta escalabilidade e uma relativa dificuldade na instalação.

MongoDB um equilíbrio entre a familiaridade ea facilidade de utilização do MySQL, ea franqueza e desempenho oferecidos pelos bancos de dados de armazenamento de documentos. O banco de dados não tem esquema definido de modo que você pode adicionar, remover e modificar a estrutura dos seus documentos sem ter que emitir uma instrução UPDATE.

Instalação & Configuração

A instalação do MongoDB é realmente fácil. Na configuração é necessário apenas que crie o diretório Mongo para armazenar os dados. No Windows a localização default é C:\data\db e em *ni é /data/db/. Uma vez criado o diretório, faça o download do binário apropriado do Mongo na págida de downloads (http://www.mongodb.org/display/DOCS/Downloads) e execute o arquivo bin/mongod. Mongo agora já deve estar instalado e rodando.

Agora nós precisamos instalar a extensão do MongoDB pra PHP. Se seu sistema é Linux ou Mac OS você pode usar a ferramenta pecl que é empacotado com o PHP. Com o comando sudo pecl install mongo ele baixa automaticamente o arquivo, compila e adiciona a extensão no php.ini. Se seu sistema for Windows você precisa fazer o dawnload do binário adequando (http://www.mongodb.org/display/DOCS/Installing+the+PHP+Driver#InstallingthePHPDriver-WindowsInstall), copiar php_mongo.dll para seu diretório e adicionar a linha extension=php_mongo.dll no arquivo php.ini. Reinicie o servidor web e tudo deve ser instalado e funcionando.

Empacotador MongoDB

class mongo
{

	public $connection;
	public $collection;

	public function __construct($host = 'localhost:27017')
	{
		$this->connection = new \Mongo($host);
	}

	public function setDatabase($c)
	{
		$this->db = $this->connection->selectDB($c);
	}

	public function setCollection($c)
	{
		$this->collection = $this->db->selectCollection($c);
	}

	public function insert($f)
	{
		$this->collection->insert($f);
	}

	public function get($f)
	{
		$cursor = $this->collection->find($f);

		$k = array();
		$i = 0;

		while( $cursor->hasNext())
		{
		    $k[$i] = $cursor->getNext();
			$i++;
		}

		return $k;
	}

	public function update($f1, $f2)
	{
		$this->collection->update($f1, $f2);
	}

	public function getAll()
	{
		$cursor = $this->collection->find();
		foreach ($cursor as $id => $value)
		{
			echo "$id: ";
			var_dump( $value );
		}
	}

	public function delete($f, $one = FALSE)
	{
		$c = $this->collection->remove($f, $one);
		return $c;
	}

	public function ensureIndex($args)
	{
		return $this->collection->ensureIndex($args);
	}

}

Usando nosso empacotador MongoDB

Com MongoDB instalado e rodando a classe escrita nós podemos agora começar a interagir com alguns dados. Começamos por instanciar a nossa classe, em seguida, criar um novo banco de dados e collection. Ambos os bancos de dados e collection são feitas na hora. A collection é equivalente em MongoDB de uma tabela no banco de dados SQL, apenas mantém os dados.

$m = new mongo();
$m->setDatabase('query7');
$m->setCollection('data');

Agora vamos inserir alguns dados na collection. Observe que o valor de tutorials é um array. O MongoDB suporta estas estruturas de dados nativamente e os valores nelas podem ser pesquisados e consultados.


$m->insert(array(

'url' => 'http://www.query7.com',
'software' => 'wordpress',
'tutorials' => array('php','javascript','web development'),
));

Nós podemos fazer uma simples pesquisa e selecione todos os documentos onde url = http://www.query7.com. Para localizar todos os documentos com desenvolvimento web na matriz tutoriais que precisamos para definir tutoriais como um índice. Como você poderia imaginar que esta também é direta foward.

$m->get(array('url' => 'http://www.query7.com'));
$m->ensureIndex(array('tutorials' => 1);
$m->get(array('tutorials' = 'php'));

As atualizações são fáceis de problema também. O primeiro parâmetro é a condição que os dados sejam atualizados devem satisfazer (semelhante a WHERE em SQL), o segundo são as mudanças que queremos fazer com esses dados. Note que o segundo parâmetro é a chave $set. Ao usar $set mantemos o restante dos dados em nosso documento (url, tutoriais) intacta. Se não usamos $set, então todo o documento conterá apenas a chave software e o valor wordpress2.

$m->update(array('url' => 'http://www.query7.com'), array('$set' => array('software' => 'wordpress2')), true);

Finalmente vamos querer excluir dados. Nosso método de apagar tem um argumento, as condições que os dados devem satisfazer.

$m->delete(array('software' => 'wordpress2'));

Espero que esta demonstração mostre como é fácil usar o MongoDb. Recomendo fortemente que você use o Mongo em seu próximo projeto.

Leitura adicional:

Artigo traduzido do blog: http://query7.com/mongodb-php-tutorial

Comentem!


Fala pessoal, boa tarde.
Apesar de andar muito sem tempo ultimamente. Consegui uma brecha e vim aqui postar.
Bem vou postar hoje uma classe que serve pra fazer downloads de arquivos via FTP. Serve também pra você ter uma noção de como isso funciona.

Ftp.Class.php


<?php

Class Ftp {
private $host;
private $login;
private $password;
private $serverDir;
private $localDir;
private $conn;

public function __construct($host, $login, $password, $serverDir, $localDir) {
$this->host			= $host;
$this->login		= $login;
$this->password		= $password;
$this->serverDir	= $serverDir;
$this->localDir		= $localDir;
}

public function getFiles($fileType=false) {
if ($this->connect()) {
$files	= ftp_nlist($this->conn, $this->serverDir);
foreach($files as $file) {
$this->downloadFile($file, $fileType);
}
}
$this->disconnect();
}

private function disconnect() {
ftp_close($this->conn);
}

private function connect() {
$this->conn	= ftp_connect($this->host);
return ftp_login($this->conn, $this->login, $this->password);
}

private function downloadFile($file, $fileType) {
if ($fileType){
$prefixLength	= strlen($fileType);
if (substr($file, -$prefixLength) == $fileType) {
ftp_get($this->conn, $this->localDir.substr($file, strlen($this->serverDir)), $file, FTP_BINARY);
}
}else {
ftp_get($this->conn, $this->localDir.substr($file, strlen($this->serverDir)), $file, FTP_BINARY);
}
}
}

Bem, é isso aí pessoal.
Qualquer dúvida só perguntar.

Abraços!


Boa noite pessoal.
Hoje vou falar sobre como empacotar um código PHP em .phar.

Pra começarmos, o que é isso? Bem, em uma linguagem bem clara é como se juntássemos todo o código de um sistema em um só arquivo.
Como instalar? A partir do php 5.3 esse pacote já vem incluso, mas caso vc use uma versão anterior pode-se instalar pelo PEAR:
http://pecl.php.net/package/phar

E como eu gero o arquivo? Vamos desenvolver o arquivo cria_phar.php :


/**
 * Instancia a classe Phar
 * @param Primeiro caminho no sistema de arquivos onde será criado ou acessado o arquivo Phar.
 * @param Segundo são flags passadas para a classe pai.
 * @param Terceiro É um parâmetro que pode ser utilizado pra chamar o phar em funções de stream
 */
$p = new Phar('app.phar', 0, 'app.phar');
# Faz com que as mudanças no arquivo .phar só sejam aplicadas após completo o script
$p->startBuffering();
# Adiciona um arquivo ao phar
$p->addFile("/projeto1/login.php");
# Adiciona o conteúdo de um diretório ao arquivo .phar, no caso só os arquivos com extensão .php
$p->buildFromDirectory('/projeto2', '/\.php/');
# Adicionar todo o conteúdo de um diretório ao arquivo .phar
$p->buildFromDirectory('/projeto3');
# Seta um código a ser realizado quando o arquivo .phar for carregado
$p->setStub($p->createDefaultStub('index.php'));
# Aplica as mudanças ao arquivo .phar
$p->stopBuffering();

Agora é só chamar http://localhost/cria_phar.php e seu arquivo app.phar será criado. 🙂
Espero que senha sido claro, qualquer dúvida é só perguntar.

Algumas considerações finais:
– Para incluir um arquivo phar use: include ‘phar://app.phar/index.php’;
– Talvez seja necessário você setar no php.ini phar.readonly para Off
– Talvez seja necessário também mudar a linha
AddType application/x-httpd-php .php para AddType application/x-httpd-php .php .phar
– E em alguns casos, principalmente os usuários de mac. Quando ao processar o arquivo .phar o PHP devolver apenas “?????”, várias interrogações você precisa adicionar ao php.ini detect_unicode = Off

Abraços!


Bom dia pessoal, e na semana do PHP acabei de criar uma classe pra tratamento de erros segue abaixo:


<?php

/**

* Classe voltada para tratamento de erros.

* Class for handling errors.

*

* @license Classe livre. Poder ser editada e utilizada como quiser.

* @license Class free. Can be edited and used as you wish.

* @example require_once "Error.php"; $error = new Error();

*

* @author tiagobutzke

* @version 1.0

*

* 01/09/2010

*/

Class Error {

private $mailTo			= "tiago.butzke@gmail.com";

private $mailFrom		= "no-reply@gmail.com.br";

private $mailReplyTo	= "tiago.butzke@gmail.com";

private $mailMode		= 1;

private $userErrors		= array(

E_WARNING,

E_USER_ERROR,

E_USER_WARNING,

E_USER_NOTICE

);

private $errorType		= array (

E_ERROR => "ERRO FATAL",

E_WARNING => "ALERTA",

E_PARSE => "ERRO DE SINTAXE",

E_NOTICE => "AVISO",

E_CORE_ERROR => "ERRO DE PROCESSAMENTO",

E_CORE_WARNING => "ALERTA DE PROCESSAMENTO",

E_COMPILE_ERROR => "ERRO DE COMPIL&Ccedil;&Atilde;O",

E_COMPILE_WARNING => "ALERTA DE COMPILA&Ccedil;&Atilde;O",

E_USER_ERROR => "ERRO DO USU&Aacute;RIO",

E_USER_WARNING => "ALERTA DO USU&Aacute;RIO",

E_USER_NOTICE => "AVISO DO USU&Aacute;RIO",

E_STRICT => "AVISO ESTRITO"

);

private $ignoreErrors	= array(E_NOTICE, E_WARNING);

private $logMode		= 1;

private $logFile		= "error.xml";

private $logMsg;

private $redirectTo		= "leo.php";

private	$t = "\t";

private $el = "\r\n";

private $oldHandler;

private $corpMsg;

public function Error() {

}

public function register() {

$this->oldHandler	= set_error_handler(array($this, "catchMyErrors"));

}

public function restore() {

set_error_handler($this->oldHandler);

return $this;

}

private function ignoreErrors() {

if (!in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1')) && in_array($errno, $this->getIgnoreErrors())) {

return ;

}

}

private function setCorpMsg($var) {

$consCorpMsg	= array("CRDT", "CRERRNO", "CRERRORTYPE", "CRERRMSG", "CRFILENAME", "CRLINENUM");

$corp			= "<b>Informa&ccedil;&otilde;es sobre o erro:</b>".$this->el;

$corp			.= "<ul>".$this->el;

$corp			.= $this->t."<li>Data e hora: CRDT</li>".$this->el;

$corp			.= $this->t."<li>Tipo: CRERRNO CRERRORTYPE</li>".$this->el;

$corp			.= $this->t."<li>Descri&ccedil;&atilde;o: <small> CRERRMSG </small></li>".$this->el;

$corp			.= $this->t."<li>Arquivo: CRFILENAME</li>".$this->el;

$corp			.= $this->t."<li>Linha: CRLINENUM</li>".$this->el;

$corp			.= "</ul>";

$this->corpMsg	= str_replace($consCorpMsg, $var, $corp);

}

private function setLogMsg($var) {

$this->logMsg["line"]		= $var[0];

$this->logMsg["file"]		= $var[1];

$this->logMsg["message"] 	= $var[2];

$this->logMsg["datetime"]	= $var[3];

//		$consLogMsg		= array("LGLINENUM", "LGFILENAME", "LGERRMSG", "LGDT");

//		$corp			= $this->t."line='LGLINENUM' file='LGFILENAME' message='LGERRMSG' datetime='LGDT'".$this->el;

//		$this->logMsg	= str_replace($consLogMsg, $var, $corp);

}

private function saveLog($errno) {

if (!file_exists($this->logFile))

$this->createFileLog();

$xml 	= simplexml_load_file($this->logFile);

$exist 	= false;

foreach ($xml->error as $errorLine)

if ($errorLine["code"] == $errno) {

$child	= $errorLine->addChild("details");

$this->createLogDetails($child);

$exist 	= true;

break;

}

if (!$exist) {

$error	= $xml->addChild("error");

$error->addAttribute("code", $errno);

$child	= $error->addChild("details");

$this->createLogDetails($child);

}

file_put_contents($this->logFile, $xml->asXML());

}

private function createLogDetails($child) {

$child->addAttribute("line", $this->logMsg["line"]);

$child->addAttribute("file", $this->logMsg["file"]);

$child->addAttribute("message", $this->logMsg["message"]);

$child->addAttribute("datetime", $this->logMsg["datetime"]);

}

private function createFileLog() {

$corp	= "<?xml version='1.0' encoding='ISO-8859-1'?>".$this->el;

$corp	.= $this->t.'<errors>'.$this->el;

$corp	.= $this->t.'</errors>';

$file	= fopen($this->logFile, "w+");

fwrite($file, $corp);

fclose($file);

}

private function sendMail() {

$subject	= "Alerta de erro em: ".$_SERVER['REQUEST_URI'];

$headers 	= "MIME-Version: 1.0".$this->el;

$headers 	.= "Content-type: text/html; charset=ISO-8859-1".$this->el;

$headers 	.= 'To: '. $this->mailTo.$this->el;

$headers	.= 'From: '. $this->mailFrom .$this->el;

mail($this->mailTo, $subject, $this->corpMsg, $headers);

}

private function redirect() {

header('Location:'.$this->redirectTo);

}

public function catchMyErrors($errno, $errmsg, $filename, $linenum, $vars) {

try {

$this->ignoreErrors();

$dt	= date("Y-m-d H:i:s");

$errmsg = $str = mb_convert_encoding($errmsg, "ISO-8859-1", "ASCII,JIS,UTF-8,ISO-8859-1");

$this->setCorpMsg(array($dt, $errno, $this->errorType[$errno]), $errmsg, $filename, $linenum);

if (in_array($errno, $this->userErrors)) {

if ($this->logMode == 1) {

$this->setLogMsg(array($linenum, $filename, $errmsg, $dt));

$this->saveLog($errno);

}

if ($this->mailMode == 1) {

$this->sendMail();

}

$this->redirect();

}

}catch (Exception $e) {

$this->restore();

}

}

}

Qualquer dúvida só perguntar. Abraços.