Ir para conteúdo
Fórum Script Brasil

neto.joaobatista

Membros
  • Total de itens

    116
  • Registro em

  • Última visita

Tudo que neto.joaobatista postou

  1. Amigo, salva o código abaixo em um arquivo chamado Mail.php: <?php /** * Envia emails utilizando autenticação em um servidor SMTP */ abstract class Mail { /** * Recurso retornado pelo fsockopen * @var resource */ static private $smtp; /** * Servidor SMTP * @var string */ static private $smtp_host; /** * Porta do servidor SMTP * @var integer */ static private $smtp_port; /** * Nome do usuário * @var string */ static private $smtp_user; /** * Senha do usuário * @var string */ static private $smtp_pswd; /** * Define se a classe já foi configurada * @var boolean */ static private $configured; /** * Lista de cabeçalhos * @var array */ static private $headers; /** * Configura o envio de email * * @param string $host O servidor de SMTP * @param integer $port A porta usada pelo servidor (padrão 25) * @param string $user O nome do usuário * @param string $pswd A senha */ static public function configure( $host , $port = 25 , $user , $pswd ){ $errno = 0; $error = ""; self::$smtp_host = $host; self::$smtp_port = $port; self::$smtp_user = $user; self::$smtp_pswd = $pswd; self::$headers = array(); if ( ( self::$smtp = fsockopen( self::$smtp_host , self::$smtp_port , $errno , $error , 1 ) ) ){ self::$configured = true; } else { throw new Exception( sprintf( "Não foi possível criar socket com o servidor, Erro[ %d ]: %s" , $errno , $error ) ); } } /** * Adiciona cabeçalhos para serem enviados para o servidor * * @static * @param string $field O nome do campo do cabeçalho * @param string $value O valor do campo */ static public function addHeader( $field , $value ){ self::$headers = array( "field" => $field , "value" => $value ); } /** * Fecha a conexão * * @param boolean $force Evita a verificação do comando QUIT destruindo direto o socket */ static private function close( $force = false ){ if ( self::$smtp ){ fputs( self::$smtp , "QUIT\r\n" ); $resp = fgets( self::$smtp , 256 ); if ( !$force ){ if ( substr( $resp , 0 , 3 ) != "221" ){ throw new Exception( "Falha ao cancelar a conexão" ); } } fclose( self::$smtp ); } } /** * Efetua a conexão com o servidor SMTP * * @return boolean TRUE se for possível conectar ao servidor */ static private function connect(){ $ret = false; $resp = fgets( self::$smtp , 256 ); if ( substr( $resp , 0 , 3 ) == "220" ){ /** * Tentamos iniciar diálogo com o servidor */ fputs( self::$smtp , sprintf( "HELO %s\r\n" , self::$smtp_host ) ); $resp = fgets( self::$smtp , 256 ); if ( substr( $resp , 0 , 3 ) == "250" ){ /** * Tentamos iniciar autenticação */ fputs( self::$smtp , "auth login\r\n" ); $resp = fgets( self::$smtp , 256 ); if ( substr( $resp , 0 , 3 ) == "334" ){ /** * Enviamos o nome do usuário primeiro */ fputs( self::$smtp , sprintf( "%s\r\n" , base64_encode( self::$smtp_user ) ) ); $resp = fgets( self::$smtp , 256 ); if ( substr( $resp , 0 , 3 ) == "334" ){ /** * Enviamos a senha do usuário */ fputs( self::$smtp , sprintf( "%s\r\n" , base64_encode( self::$smtp_pswd ) ) ); $resp = fgets( self::$smtp , 256 ); /** * Tudo ok, estamos conectados !!! */ if ( substr( $resp , 0 , 3 ) == "235" ){ $ret = true; } else { throw new Exception( "Não foi possível autenticar o usuário." ); } } else { throw new Exception( "Não foi possível enviar nome de usuário para autenticação." ); } } else { throw new Exception( "Não foi possível iniciar processo de autenticação." ); } } else { throw new Exception( "Conectamos, mas não foi possível iniciar comunicação." ); } } else { throw new Exception( "Não foi possível conectar ao servidor." ); } return( $ret ); } /** * Gera a lista de cabeçalhos para serem enviados para o servidor * * @see Mail::addHeader() * @return string */ static private function generateHeaders(){ $ret = ""; /** * Percorremos a lista de cabeçalhos e montamos a string com os campos e valores */ for ( $i = 0 , $t = count( self::$headers ); $i < $t; $i++ ){ $ret .= sprintf( "%s: %s\r\n" , self::$headers[ $i ][ "field" ] , self::$headers[ $i ][ "value" ] ); } return( $ret ); } /** * Envia uma mensagem via SMTP * @param string $from O email de quem está enviando * @param string $to O email de quem vai receber * @param string $subject O assunto do email * @param string $message A mensagem do email (pode conter HTML) * @return boolean TRUE se o email for enviado com sucesso */ static public function send( $from , $to , $subject , $message ){ $ret = false; /** * Verificamos se estamos configurados, primeiro * @see Mail::configure() */ if ( self::$configured ){ /** * Tentamos conectar utilizando as configurações passadas */ if ( self::connect() ){ /** * Estamos conectados, vamos definir o campo FROM */ fputs( self::$smtp , sprintf( "MAIL FROM: <%s>\r\n" , $from ) ); $resp = fgets( self::$smtp , 256 ); if ( substr( $resp , 0 , 3 ) == "250" ){ /** * Campo FROM definido, vamos definir o recipiente TO */ fputs( self::$smtp , sprintf( "RCPT TO: <%s>\r\n" , $to ) ); $resp = fgets( self::$smtp , 256 ); if ( substr( $resp , 0 , 3 ) == "250" ){ /** * Tudo certo até agora, vamos tentar iniciar envio dos dados */ fputs( self::$smtp , "DATA\r\n" ); $resp = fgets( self::$smtp , 256 ); if ( substr( $resp , 0 , 3 ) == "354" ){ /** * Enviando o email... */ fputs( self::$smtp , sprintf( "To: %s\r\nFrom: %s\r\nSubject: %s\r\n%s\r\n\r\n%s\r\n.\r\n", $to, $from, $subject, self::generateHeaders(), $message ) ); $resp = fgets( self::$smtp , 256 ); if ( substr( $resp , 0 , 3 ) == "250" ){ /** * Email enviado !!! */ $ret = true; self::close(); } else { throw new Exception( "Falha ao enviar a mensagem" ); } } else { throw new Exception( "Falha ao iniciar envio da mensagem" ); } } else { throw new Exception( "Falha ao definir campo TO" ); } } else { throw new Exception( "Falha ao definir campo FROM" ); } } } return( $ret ); } } ?> Ai você usa assim: $from = eu@dominio.com; $to = voce@dominio.com; $subject = "Testando envio de email"; $message = "Hey, tudo certo ?"; try { Mail::configure( "smtp.dominio.com" , 25 , "usuario" , "senha" ); Mail::send( $from , $to , $subject , $message ); printf( "Email enviado com sucesso !!!" ); } catch( Exception $e ){ printf( $e->getMessage ); } []'s J. Neto
  2. Kara, não sei se entendi direito, você tem uma tabela +- assim: mysql> SELECT * FROM corridas c; +----+--------+-----------+ | id | nrLote | valorLote | +----+--------+-----------+ | 1 | 3 | 12.000 | | 2 | 3 | 7.000 | | 3 | 3 | 4.000 | | 4 | 2 | 5.000 | | 5 | 2 | 25.000 | | 6 | 2 | 15.000 | | 7 | 1 | 15.000 | | 8 | 1 | 2.000 | | 9 | 1 | 1.000 | +----+--------+-----------+ 9 rows in set (0.00 sec) Ai você quer agrupar os lotes com o maior valor do lote, se for isso: SELECT nrLote,max(valorLote) FROM corridas c GROUP BY nrLote Isso irá retornar: mysql> SELECT nrLote,max(valorLote) "valorLote" FROM corridas c GROUP BY nrLote; +--------+-----------+ | nrLote | valorLote | +--------+-----------+ | 1 | 15.000 | | 2 | 25.000 | | 3 | 12.000 | +--------+-----------+ 3 rows in set (0.00 sec) []'s J. Neto
  3. A comparação entre strings é sempre lenta, por isso, sempre que temos em uma tabela, uma string que se repete para N registros é conveniente separá-la em uma tabela e utilizar um relacionamento. Pelo nome da sua coluna "STATUS" eu não acredito que você tenha um número muito grande de status possíveis. Se o status for um campo volátil (onde é possível adicionar ou remover um status existente) então eu criaria uma tabela para os status possíveis e utilizaria um id para relacionar, se o status for um conjunto de valores fixos que nunca serão modificados então eu modificaria esse campo de VARCHAR para um ENUM contendo todas as possibilidades existentes. Quanto ao código de barras, você tem o problema do tamanho do número, nesse caso você pode "Dividir para conquistar", eu separaria seu código de 24 dígitos em 4 módulos de 6 dígitos; Dessa forma o maior número de um dos módulos estaria ainda dentro do limite de um UNSIGNED INT. Ex: $codigo = "123456789012345678901234"; $part1 = 123456; $part2 = 789012; $part3 = 345678; $part4 = 901234; Dessa forma, por maior que seja uma das partes, sempre será um INT sem sinal (0 - 4294967295) Feito isso você pode criar sua tabela que conterá o código de barra, particionando-a de forma vertical CREATE TABLE CB ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, A INT UNSIGNED NOT NULL, B INT UNSIGNED NOT NULL, C INT UNSIGNED NOT NULL, D INT UNSIGNED NOT NULL, PRIMARY KEY( id , A ), INDEX parts( A , B , C , D ) ) ENGINE = MyISAM PARTITION BY RANGE ( A )( PARTITION p0 VALUES LESS THAN ( 99999 ), PARTITION p1 VALUES LESS THAN ( 199998 ), PARTITION p2 VALUES LESS THAN ( 299997 ), PARTITION p3 VALUES LESS THAN ( 399996 ), PARTITION p4 VALUES LESS THAN ( 499995 ), PARTITION p5 VALUES LESS THAN ( 599994 ), PARTITION p6 VALUES LESS THAN ( 699993 ), PARTITION p7 VALUES LESS THAN ( 799992 ), PARTITION p8 VALUES LESS THAN ( 899991 ), PARTITION p9 VALUES LESS THAN MAXVALUE ) Bom, para teste eu populei essa tabela com 16000000 de registros e fiz uma pesquisa por um código de barras: SELECT id , concat( A , B , C , D ) "cb" FROM CB WHERE ( A = 100015 ) AND ( B = 350198 ) AND ( C = 600381 ) AND ( D = 850564 ); O resultado foi: mysql> SELECT id , concat( A , B , C , D ) "cb" FROM CB WHERE ( A = 100015 ) AND ( B = 350198 ) AND ( C = 600381 ) AND ( D = 850564 ); +---------+--------------------------+ | id | cb | +---------+--------------------------+ | 9521226 | 100015350198600381850564 | +---------+--------------------------+ 1 row in set (0.00 sec) Mesmo com 16.000.000 de registros o resultado da query foi instantâneo, isso porque: mysql> explain SELECT id , concat( A , B , C , D ) "cb" FROM CB WHERE ( A = 100015 ) AND ( B = 350198 ) AND ( C = 600381 ) AND ( D = 850564 ); +----+-------------+-------+------+---------------+-------+---------+-------------------------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+-------+---------+-------------------------+------+-------+ | 1 | SIMPLE | CB | ref | parts | parts | 16 | const,const,const,const | 1 | | +----+-------------+-------+------+---------------+-------+---------+-------------------------+------+-------+ 1 row in set (0.00 sec) mysql> SELECT count(*) FROM CB WHERE ( A = 100015 ) AND ( B = 350198 ) AND ( C = 600381 ) AND ( D = 850564 ); +----------+ | count(*) | +----------+ | 1 | +----------+ 1 row in set (0.00 sec) mysql> explain SELECT count(*) FROM CB WHERE ( A = 100015 ) AND ( B = 350198 ) AND ( C = 600381 ) AND ( D = 850564 ); +----+-------------+-------+------+---------------+-------+---------+-------------------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+-------+---------+-------------------------+------+-------------+ | 1 | SIMPLE | CB | ref | parts | parts | 16 | const,const,const,const | 1 | Using index | +----+-------------+-------+------+---------------+-------+---------+-------------------------+------+-------------+ 1 row in set (0.00 sec) Em vez de utilizar uma comparação de string, utilizamos 4 valores constantes. Usando o PHP para separar o código em partes: /** * Separa uma string que representa um código de barras de 24 digitos em blocos numéricos * @param string $numstr O código de barras * @param integer $parts O número de blocos * @param integer $length O tamanho máximo do código * @return array Matriz contendo os blocos numéricos */ function str2numPart( $numstr , $parts = 4 , $length = 24 ){ $ret = array(); /** * Verificamos se o tamanho da string é exatamente igual ao valor do parâmetro $length */ if ( ( $clength = strlen( $numstr ) ) == $length ){ $bloco = floor( $length / $parts ); /** * Separamos a string na quantidade de blocos definida pelo parâmetro $parts */ while ( strlen( $numstr ) ){ $ret[] = (int) substr( $numstr , 0 , $bloco ); $numstr = substr( $numstr , $bloco ); } } else { throw new UnexpectedValueException( sprintf( "A representação do número deve ter de comprimento exatamente %d, %d foi dado" , $length , $clength ) ); } return( $ret ); } $nustr = "100015350198600381850564"; $sql = sprintf( "SELECT count(*) FROM CB WHERE %s;" , vsprintf( "( A = %d ) AND ( B = %d ) AND ( C = %d ) AND ( D = %d )" , str2numPart( $nustr ) ) ); var_dump( $sql ); //string(102) "SELECT count(*) FROM CB WHERE ( A = 100015 ) AND ( B = 350198 ) AND ( C = 600381 ) AND ( D = 850564 );" []'s J. Neto
  4. Bom amigo, Uma coisa que eu costumo dizer para meus cliente tem exatamente a ver com isso tudo que você disse: "Você tem aquilo que você paga". abraços... J. Neto
  5. Sim, de fato a coluna `id` é ambígua, isso porque você está utilizando uma coluna `id` no primeiro select e uma no segundo JOIN. A ambiguidade está exatamente ai, no segundo select. Quando você disse para fazer o JOIN com o cats s e depois o LEFT JOIN com o cats s2 e comparou os `id` você esqueceu de usar o alias da tabela. Troque essa parte do seu código por: LEFT JOIN cats s2 ON ( s2.pcat_id = s.pcat_id ) AND ( s2.id < s.id ) Acho que isso deve resolver... []'s J. Neto
  6. Sim, claro... O ponto de utilizar o ID e não a string é exatamente para ganharmos em velocidade. Existem casos em que a comparação entre strings é de fato necessária, mas não acho que esse seja o caso. A tabela de usuários sempre crescerá verticalmente, assim como a tabela de relacionamentos (tb_connection) mas a tabela de adjetivos chegará em um ponto em que ela parará de crescer e sou capaz de apostar que ela jamais chegará a mais de uma dezena. Com a tabela de adjetivos sempre pequena podemos ter uma caixa de combinação com os adjetivos referenciando aos ids da tabela de adjetivos. A questão pode não ser importante quando falamos em algumas centenas de registros, mas se o número chega em algumas centenas de milhares ou até milhões, então a comparação entre strings pode ser um problema. []'s J. Neto
  7. Só comparando: mysql> explain SELECT STRAIGHT_JOIN u.name FROM tb_user u INNER JOIN tb_connection t ON t.ID_user = u.ID INNER JOIN tb_adj a ON a.ID = t.ID_adj WHERE a.name ='sexy' AND u.ID IN ( SELECT STRAIGHT_JOIN t2.ID_user FROM tb_connection t2 INNER JOIN tb_adj a2 ON a2.ID = t2.ID_adj WHERE a2.name = 'rich'); +----+--------------------+-------+--------+---------------+---------+---------+---------------+------+--------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+-------+--------+---------------+---------+---------+---------------+------+--------------------------------+ | 1 | PRIMARY | u | ALL | PRIMARY | NULL | NULL | NULL | 4 | Using where | | 1 | PRIMARY | t | ALL | NULL | NULL | NULL | NULL | 6 | Using where; Using join buffer | | 1 | PRIMARY | a | eq_ref | PRIMARY | PRIMARY | 3 | test.t.ID_adj | 1 | Using where | | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | NULL | NULL | NULL | 6 | Using where | | 2 | DEPENDENT SUBQUERY | a2 | ALL | PRIMARY | NULL | NULL | NULL | 5 | Using where; Using join buffer | +----+--------------------+-------+--------+---------------+---------+---------+---------------+------+--------------------------------+ 5 rows in set (0.00 sec) mysql> explain SELECT u.name, c.ID_user, c.ID_adj "adj1", c2.ID_adj "adj2" FROM tb_connection c JOIN tb_connection c2 ON ( c2.ID_adj = 2 ) AND ( c.ID_adj = 3 ) AND ( c2.ID_user = c.ID_user ) LEFT JOIN tb_user u ON u.ID = c.ID_user; +----+-------------+-------+--------+---------------+---------+---------+----------------+------+--------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+--------+---------------+---------+---------+----------------+------+--------------------------------+ | 1 | SIMPLE | c | ALL | NULL | NULL | NULL | NULL | 6 | Using where | | 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 3 | test.c.ID_user | 1 | | | 1 | SIMPLE | c2 | ALL | NULL | NULL | NULL | NULL | 6 | Using where; Using join buffer | +----+-------------+-------+--------+---------------+---------+---------+----------------+------+--------------------------------+ 3 rows in set (0.00 sec) []'s J. Neto
  8. Então a query tem que retornar apenas a Mary, é isso ?? Se for tenta ai: SELECT u.name, c.ID_user, c.ID_adj "adj1", c2.ID_adj "adj2" FROM tb_connection c JOIN tb_connection c2 ON ( c2.ID_adj = 2 ) AND ( c.ID_adj = 3 ) AND ( c2.ID_user = c.ID_user ) LEFT JOIN tb_user u ON u.ID = c.ID_user []'s J. Neto
  9. Amigo, tive um caso semelhante e cheguei a conclusão que é inviável fazer "esse tipo específico" de upload múltiplo. Isso porque essas fotos são para encadernação e consequentemente acabam possuindo 5Mib cada uma. A solução que encontrei foi utilizar o PHP-GTK e desenvolver uma aplicação "standalone" para rodar no desktop do cliente, permitindo assim um controle de fluxo. A diferença do meu cliente é que ele que faz as encadernações, e precisava disponibilizar para os clientes dele essa solução. (enviar as fotos para encadernação) Mas como dica: 1. Upload por formulário não rola, a conexão do seu cliente pode cair ou se tornar instável e a foto chegar quebrada para a encadernação. E se você estiver enviando uma lista com 100 fotos, seu cliente não saberá exatamente qual foto da lista deu problema de upload até que o pessoal da encadernação entre em contato relatando o problema. 2. Independente da forma que você implemente a solução, extraia o hash da foto antes de enviar e compare com o hash da foto que chegou ao servidor. É a única forma de garantir que a foto chegou integra ao destino. []'s J. Neto
  10. neto.joaobatista

    Controle de estoque

    Para fazer isso você pode utilizar o JQuery, Dojo, Ext ou qualquer framework para Javascript que você melhor se adaptar. Assim você poderá modificar o DOM dinamicamente e ir adicionando ou removendo as linhas na sua tabela de produtos. Independente do framework que você utilizar, lembre-se de utilizar [] na hora de definir os produtos para que sejam enviados para o PHP como uma matriz: <input type="hidden" name="produtos[][ 'name' ]" value="p1" /> <input type="hidden" name="produtos[][ 'name' ]" value="p2" /> Quando o usuário terminar de adicionar ou remover os itens que ele quiser você vai enviar os dados para o PHP, como você utilizou [] nos seus "inputs" você conseguirá facilmente percorrer a lista com um loop for: if ( isset( $_REQUEST[ "produtos" ] ) ){ $produtos = $_REQUEST[ "produtos" ]; $values = ""; for ( $i = 0 , $t = count( $produtos ); $i < $t; $i++ ){ $values .= sprintf( "%s(NULL , '%s' )" , empty( $values ) ? "" : ", " , $produtos[ $i ][ "name" ] ); } if ( !empty( $values ) ){ $sql = sprintf( "insert into produtos( `id` , `name` ) values %s" , $values ); } } []'s J. Neto
  11. Amigo, tenta modificar sua query para: SELECT t.nome,t.artista, CAST( t.votos AS UNSIGNED ) "votos" FROM top10 t ORDER BY "votos" DESC LIMIT 10 []'s J. Neto
  12. Amigo, isso está mais para um problema de SQL que um problema de PHP, basicamente você vai utilizar uma única query: SELECT c.cat_id, c.cat_nome, s.scat_id, s.scat_nome,s.cat_id FROM pcategoria c JOIN scategoria s ON s.cat_id = c.cat_id LEFT JOIN scategoria s2 ON ( s2.cat_id = s.cat_id ) AND ( s2.scat_id < s.scat_id ) GROUP BY c.cat_id, c.cat_nome, s.scat_id, s.scat_nome HAVING COUNT( s2.scat_id ) < 3 ORDER BY c.cat_nome, s.scat_nome; Você vai perceber na cláusula HAVING a função COUNT( s2.scat_id ) < 3, esse 3 é o número de registros de cada subgrupo. Utilizando os seus dados irá retornar o seguinte: +--------+----------+---------+-----------+--------+ | cat_id | cat_nome | scat_id | scat_nome | cat_id | +--------+----------+---------+-----------+--------+ | 2 | cores | 2 | azul | 2 | | 2 | cores | 1 | marrom | 2 | | 2 | cores | 3 | vermelho | 2 | | 1 | tipos | 6 | acetinado | 1 | | 1 | tipos | 8 | espelhado | 1 | | 1 | tipos | 7 | fosco | 1 | +--------+----------+---------+-----------+--------+ 6 rows in set (0.00 sec) []'s J.Neto
  13. Hey Marcelo, tenta assim: /** * Converte um número em ponto flutuante para a representação monetária segundo o padrão brasileiro * * @param float $float O valor que será convertido * @param integer $dec O número de casas decimais * @param boolean $round Define se o valor será arredondado ou se será apenas cortado * @param string $dec_sep O separador de casas decimais * @param string $mil_sep O separador de milhares * @return string O valor convertido */ function brReal( $float , $dec = 2 , $round = false , $dec_sep = "," , $mil_sep = "." ){ if ( $round ){ if ( ( $float = round( $float * pow( 10 , $dec ) ) ) ) $float /= pow( 10 , $dec ); } $str = (string) $float; $mtc = array(); if ( preg_match( "/([0-9]+)(?:\.){1}([0-9]+)?/" , $str , $mtc ) ){ $str = sprintf( "%d.%s" , $mtc[ 1 ] , substr( $mtc[ 2 ] , 0 , $dec ) ); } return( sprintf( "R\$ %s" , number_format( $str , $dec , $dec_sep , $mil_sep ) ) ); } $num = 100.99; $par = 10; $fim = $num / $par; echo brReal( $fim ); //R$ 10,09 echo brReal( $fim , 3 ); //R$ 10,099 echo brReal( $fim , 2 , true ); //R$ 10,10 echo brReal( 1000000.99 / 10 , 2 ); //R$ 100.000,09 echo brReal( 1000000.99 / 10 , 2 , false , "." , "'" ); //R$ 100'000.09 echo brReal( 1000000.99 / 10 , 2 , false , "." , "" ); //R$ 100000.09 []'s J. Neto
  14. Amigo, tenta executar esse código aqui, ele é o seu mesmo código que eu adicionei algumas mensagens de erro, se não funcionar você saberá onde está o problema: try { if ( isset( $_FILES[ "fotoalbum" ] ) ){ $arquivo = $_FILES[ "fotoalbum" ]; $pasta_dir = "../albuns"; $arquivo_nome = sprintf( "%s/%s" , $pasta_dir , $arquivo[ "name" ] ); $query = "SELECT id FROM fotos ORDER BY id DESC LIMIT 1"; /** * Sempre verifique se sua consulta foi executada corretamente, adminir que uma consulta sempre vá retornar * um recurso é um erro que pode custar a segurança da sua aplicação. */ if ( ( $result = @mysql_query( $query ) ) ){ $name = null; /** * Quando você define a variável $name dentro de um bloco (nesse caso o bloco while) ela é visível apenas para o bloco que a definiu. * Quando você precisar usar uma variável que precisa ser visível fora de um bloco você deve defini-la antes de utilizá-la */ while ( ( $row = mysql_fetch_array( $result ) ) ){ $t = $row[ "id" ] + 1; $name = sprintf( "%s.jpg" , $t ); } if ( file_exists( $arquivo[ "tmp_name" ] ) ){ move_uploaded_file( $arquivo[ "tmp_name" ] , $arquivo_nome ); $newname = sprintf( "%s/%s" , $pasta_dir , $name ); $origem = basename( $arquivo_nome ); $destino = basename( $newname ); $destfolder = realpath( dirname( $newname ) ); if ( file_exists( $origem ) ){ if ( ( fileperms( $destfolder ) & 0x0080 ) == 0x0080 ){ rename( $origem , $newname ); } else { throw new Exception( "Não foi possível renomear o arquivo." ); } } else { throw new Exception( "O arquivo de origem não existe" ); } $id = $_POST[ "id_album" ]; $legenda = $_POST[ "legenda" ]; $sql = "INSERT INTO fotos (id_album, legenda, foto) VALUES ( '".$id."' , '".$legenda."' , '".$name."' )"; if( !mysql_query( $sql , $conexao ) ){ throw new Exception( "Erro ao inserir o registro" ); } } else { throw new Exception( "Não foi possível encontrar o arquivo enviado" ); } } else { throw new Exception( "Nenhum registro encontrado" ); } printf( "<script>alert('Sua foto foi inserida com sucesso!')</script>" ); } else { throw new Exception( "A foto não foi enviada" ); } } catch ( Exception $e ){ printf( "<script>alert( 'Erro ao inserir foto \n\npor favor tenta novamente!\n\nErro: %s' )</script>" , $e->getMessage() ); }
  15. Amigo, aparentemente seu código está exatamente como deveria. Se a função protegePg foi definida exatamente dessa forma e não "protegepg" ou "ProtegePg", então pode ser que o seu arquivo "seguranca.php" não está sendo encontrado. Esse é o grande problema do include: Ele inclui se encontrar o arquivo, senão ele continua a execução sem parar. Quando você for utilizar um código que está em um arquivo e a sua aplicação depende dele para continuar (exatamente o seu caso) você deve utilizar o "require" em vez do "include". Com o require, se o arquivo que está sendo incluido não existir a aplicação vai parar com um erro FATAL. require( "seguranca.php" ); protegePg(); []'s J. Neto
  16. Verdade absoluta... Cada ferramenta tem seus méritos, inclusive o notepad (para mim, kwrite). Bom, como você está começando, acho que o Dreamweaver pode ser uma boa ferramenta. Pelo que pude ver do DW a facilidade da parte de design dele pode agilizar bastante um processo simples. Porém, nunca se esqueça de ler o seu código; conheço desenvolvedores que utilizam ferramentas como o DW onde a facilidade da ferramenta é a perdição na hora de manter a aplicação. Essa é a única parte em que descordo em número, gênero e grau do Norivan, IMPORTA SIM se o código está lindo. Um código bem escrito, com comentários claros, indentações corretas, parenteses separando operações. Tudo isso faz com que amanha, quando seu código estiver com algumas centenas de milhares de linhas de código, com algumas milhares de classes, trabalhando com mais de um banco de dados, tecnologias como RPC ou SOAP, você não fique procurando uma agulha em um palheiro para encontrar um métodozinho que faz alguma coisa. Sem contar que, como de fato "os clientes estão ai querendo comprar", eles vão sempre procurar a aplicação mais robusta, mais portável, com mais possibilidade de ser mantida em desenvolvimento próprio e o código bem escrito faz a diferença nessa hora. Eu já trabalho um pouquinho diferente, gosto de trabalhar com uma única ferramenta, por isso uso o Eclipse. A vantagem do Eclipse é que você tem uma gama de plugins tão grande que praticamente tudo é feito dentro dele, basicamente meu Eclipse é Eclipse + UML Tools + DTP + WST + WTP + PDT. Com isso eu consigo fazer meus diagramas de caso de uso, ações, classes. Feito os diagramas tenho o Data Tools onde consigo conectar em qualquer banco de dados e fazer o que preciso, tenho os Web Tools onde tenho o Web Service Explorer e as ferramentas para XML, XML Schema, XSL e enfim, (opinião minha) o PDT 2.0 é a melhor ferramenta para desenvolvimento PHP que eu já conheci.
  17. Se isso resolver seu problema, você faz o seguinte teste, cole o código abaixo no seu campo de login: &6534563456' UNION SELECT 1,1,' Note que temos no UNION SELECT 2 uns, subistitua o número de uns pelo número de colunas que você tem na sua tabela menos 1, por exemplo: Você tem 4 colunas (id, login, senha,email) você coloca no seu campo: &6534563456' UNION SELECT 1,1,1,' Ai no seu campo de senha você coloca apenas o número 1 Disse para você fazer colocar direto o número de colunas do seu banco - 1 para você ver o resultado, um agressor irá testar seu formulário até descobrir o número de colunas, e ai ele ganha acesso ao seu sistema. []'s J. Neto
  18. tenta assim: /** * Manipulador da saída buferizada * * @param string $buffer O buffer de saida * @return string O novo conteúdo */ function troca( $buffer ){ /** * O conteúdo que será trocado * @var string */ $de = "\\<P\\s*align\=[^\\>]*>.*\\<\\/P\\>"; /** * O que vamos colocar no lugar de $de * @var string */ $para = "Hey, mudamos em tempo de execução !!!"; // Fazemos a troca e retornamos return( preg_replace( sprintf( "/%s/s" , $de ) , $para , $buffer ) ); } ob_start( "troca" ); $str = "<P align=left> MAYCON VINICIUS MOREIRA </P>"; echo $str; //Hey, mudamos em tempo de execução !!! ob_end_flush();
  19. Usa saída buferizada: /** * Manipulador da saída buferizada * * @param string $buffer O buffer de saida * @return string O novo conteúdo */ function troca( $buffer ){ /** * O conteúdo que será trocado * @var string */ $de = "{resultado}"; /** * O que vamos colocar no lugar de $de * @var string */ $para = "Hey, mudamos em tempo de execução !!!"; /** * Aqui escapamos as {, [ e ( que são reservados na expressão regular */ $de = preg_replace( "/\\{/" , "\{" , $de ); $de = preg_replace( "/\\}/" , "\}" , $de ); $de = preg_replace( "/\\(/" , "\(" , $de ); $de = preg_replace( "/\\)/" , "\)" , $de ); $de = preg_replace( "/\\[/" , "\[" , $de ); $de = preg_replace( "/\\]/" , "\]" , $de ); // Fazemos a troca e retornamos return( preg_replace( sprintf( "/%s/" , $de ) , $para , $buffer ) ); } ob_start( "troca" ); echo "{resultado}"; //Hey, mudamos em tempo de execução !!! ob_end_flush(); []'s J. Neto
  20. Bom, eu criaria uma classe que seria o tipo Item, esse tipo seria dinâmico, poderia conter qualquer valor e necessariamente seria serializável. Depois eu criaria outra classe que seria a lista de itens. A classe Lista seria também necessariamente serializável: tipo Item: /** * Cria um item dinâmico que pode receber qualquer tipo de valor */ class Item implements Serializable { /** * Matriz que conterá os dados do item * @var array */ private $dados; /** * Constroi o item */ public function __construct(){ $this->dados = array(); } /** * Define dinâmicamente uma nova propriedade * * @param string $name O nome da propriedade * @param mixed $value O valor da propriedade */ private function __set( $name , $value ){ $this->dados[ $name ] = $value; } /** * Recupera o valor de uma propriedade * @param string $name O nome da propriedade * @return mixed O valor da propriedade ou NULL se ela não existir */ private function __get( $name ){ $ret = null; if ( isset( $this->dados[ $name ] ) ){ $ret = $this->dados[ $name ]; } } /** * Serializa o objeto para poder ser colocado em uma variável de sessão * * @return string O objeto convertido para uma string */ public function serialize(){ $ret = serialize( $this->dados ); return( $ret ); } /** * Transforma uma string serializada de volta no objeto * * @param string $dados A string que foi serializada anteriormente */ public function unserialize( $dados ){ $this->dados = unserialize( $dados ); } } Com essa classe você pode definir qualquer propriedade dinâmicamente, por exemplo: $item = new Item(); $item->nome = "Neto"; $item->idade = 27; Depois de criar o tipo Item você vai precisar da Lista que é na verdade um container de Items: /** * Cria uma lista de itens dinâmicos que pode ser serializada para ser armazenada em uma variável de sessão */ class Lista implements Serializable { /** * Matriz que conterá nossa lista de itens * @var array */ private $dados; /** * Constroi a lista */ public function __construct(){ $this->dados = array(); } /** * Adiciona um novo item na lista * * @param Item $item O item que será adicionado na lista * @return Lista Referência ao objeto que estamos utilizando */ public function addItem( Item $item ){ $this->dados[] = $item; return( $this ); } /** * Serializa o objeto para poder ser colocado em uma variável de sessão * * @return string O objeto convertido para uma string */ public function serialize(){ $ret = serialize( $this->dados ); return( $ret ); } /** * Serializa o objeto para poder ser colocado em uma variável de sessão * * @return string O objeto convertido para uma string */ public function unserialize( $dados ){ $this->dados = unserialize( $dados ); } } Para usar a lista você faz o seguinte: $lista = new Lista(); $item1 = new Item(); $item1->nome = "Neto" $item1->valor = 10; $item2 = new Item(); $item2->nome = "João" $item2->valor = 20; $lista->addItem( $item1 ); $lista->addItem( $item2 ); Agora que você já tem o item e a lista, basta serializar para guardar em uma variável de sessão: $_SESSION[ "lista" ] = serialize( $lista ); ai quando você quiser usar a lista que está guardada na variável de sessão você faz o seguinte: $lista = unserialize( $_SESSION[ "lista" ] ); $novo = new Item(); $novo->nome = "teste"; $novo->valor = 30; $lista->addItem( $novo ); $_SESSION[ "lista" ] = serialize( $lista ); []'s J. Neto
  21. Também acredito que não vá resolver, o que acontece é que você tem uma parte do projeto em UTF-8 (padrão Linux) e outra parte ISO-8859-1 (padrão do Windows), você deverá escolher uma das duas codificações e utilizá-la em todo o projeto. Depois de escolher a sua codificação padrão, na página que contém o formulário para o envio do seu arquivo você deverá utilizar um cabeçalho HTTP para informar ao navegador o tipo de codificação que ele deverá utilizar também, essa codificação para o navegador não serve apenas para exibir corretamente os caracteres no browser mas para o envio de arquivos também. Se quiser uma sugestão, utilize sempre UTF-8, mesmo que seu projeto tenha sido feito no Windows e vá rodar em um servidor Windows, porque o conjunto de caracteres UTF-8 foi feito para aceitar um conjunto muito maior de idiomas. Só o fato de converter todos os arquivos do seu projeto para UTF-8 e depois enviar um cabeçalho HTTP para o navegador já irá resolver definitivamente o seu problema. header( "Content-Type: text/html; charset=utf-8" );
  22. Olá amigo, Quando você diz "vai rodar local" você está dizendo que vai rodar em uma intranet e a aplicação estará no servidor de rede ?? Se sim, lembre-se que o PHP pega a data e hora da maquina que ele está (no caso o seu servidor) por isso, mesmo que o usuário modifique a data de seu ponto de rede, a data e hora do servidor serão sempre constantes. Na verdade, você pode até utilizar o JavaScript para enviar para o servidor a data da maquina do usuário e comparar com a data e hora do servidor, se estiverem errados você diz para o usuário atualizar sua data. Sendo assim, você pode utilizar o timestamp da última modificação da senha e comparar com a data atual do servidor e assim saber se a senha expirou ou não. []'s J. Neto
  23. Olá amigo, lamento utilizar sua dúvida para dizer isso mas vamos lá: URL amigável NÃO É UMA IDÉIA NOVA, NÃO É UMA TECNOLOGIA NOVA, NÃO É UM CONCEITO NOVO. URL amigável não passa de uma forma organizacional, que reflete diretamente a forma que um projeto é concebido. Não existe um "script mágico" que vai organizar uma aplicação desorganizada. A facilidade de passar variáveis via URL fez com que desenvolvedores esquecessem os aspectos organizacionais de sua própria aplicação, fazendo com que o caminho para chegar em um determinado recurso se torne tão complexo, que nem "robôs inteligentes" como o do Google consigam descifrar um caminho, chegando ao ponto de o número de combinações possíveis de uma URL com várias variáveis seja tão grande que muitas vezes nem a pessoa que desenvolveu a aplicação é capaz de fazê-lo manualmente. Você deve pensar na sua URL como um caminho para um determinado recurso, assim como em um sistema de arquivos onde temos: /share/musicas/ogg/Heavy Metal/Dio/1983/Holy Diver/05 - Don't talk to strangers.ogg /share -> arquivos compartilháveis /musicas -> auto explicativo /ogg -> auto explicativo /Heavy Metal -> auto explicativo /..... -> tudo auto explicativo Organizar a estrutura de uma aplicação deve ser a primeira etapa no desenvolvimento, quando você já tem uma aplicação rodando com o caminho para um recurso "criptografado" via URL tudo fica mais difícil, seria como tentar separar por formato/genero/artista/ano/album/musica uma lista de musicas com mais de 10000 arquivos, todos misturados. Você pode tentar utilizar um método de Gateway que propuz no post http://scriptbrasil.com.br/forum/index.php?showtopic=138797, acho que para um script pronto ela poderá funcionar com poucas modificações, porém não esqueça que "uma mulher feia" será sempre uma mulher feita, mesmo maquiada ela será ainda uma "mulher feia maquiada". []'s J. Neto
  24. Bom, eu tenho feito o seguinte em todos os meus projetos: No meu .htaccess eu não preocupo em separar as partes que preciso, em vez disso jogo tudo em uma variável chamada querystring: RewriteEngine on RewriteBase / RewriteRule ^(.*)$ Gateway.php?querystring=/$0 [QSA] php_value auto_append_file index.php Esse .htacces fará com que qualquer coisa enviada via URL seja colocada dentro da variável querystring e esse conteúdo seja passado para um arquivo chamado Gateway. É no Gateway.php, que contém a classe Gateway que trato a querystring e faço os desvios necessários, quando necessário. Para que esse post não fique muito maior que já vai ficar eu preferi não montar a classe Gateway completa (a que eu uso atualmente tem mais de 1000 linhas), em vez disso eu estou enviando apenas a possibilidade de resgatar folhas de estilo e scripts javascript. O que vai acontecer é o seguinte, o usuário digita no navegador: Ex 1 - http://www.seudominio.com.br/clicalista e seu index.php receberá: var_dump( $_GET[ "pagina" ] ); //string 'clicalista' (length=10) Ex 2 - http://www.seudominio.com.br/clicalista/informatica e seu index.php receberá: var_dump( $_GET[ "pagina" ] ); //string 'clicalista' (length=10) var_dump( $_GET[ "categoria" ] ); //string 'informatica' (length=11) Ex 3 - http://www.seudominio.com.br/clicalista/in.../arg1/arg2/arg3 e seu index.php receberá: var_dump( $_GET[ "pagina" ] ); //string 'clicalista' (length=10) var_dump( $_GET[ "categoria" ] ); //string 'informatica' (length=11) var_dump( $_GET[ "argv" ] ); //array 0 => string 'arg1' (length=4) 1 => string 'arg2' (length=4) var_dump( $_GET[ "argc" ] ); //int 2 Ou seja, o primeiro argumento é sempre a página, o segundo é a categoria e os demais são passados para o index.php como uma matriz. Porém existe uma exceção, quando o primeiro argumento é o nome de um método da classe Gateway então o método é chamado recebendo todos os argumentos passados pela URL e a execução da aplicação "morre" na própria classe Gateway, não indo para o index.php. Ex 4 - http://www.seudominio.com.br/styles/arq1.c...q2.css/arq3.css Isso fará com que todos os arquivos: arq1.css, arq2.css, arq3.css, ..., arqn.css sejam lidos de uma vez só e enviados para o navegador. A vantagem desse método é que evitamos várias requisições ao servidor (chamamos todos os arquivos necessários de uma vez só). Nessa requisição styles é o nome de um método da classe Gateway, abaixo um exemplo utilizando o método scripts da classe Gateway: Ex 5 - http://www.seudominio.com.br/scripts/arq1.js/arq2.js/arq3.js Como no primeiro caso, os arquivos arq1.js, arq2.js, arq3.js, ..., arqN.js serão carregados. Como disse anteriormente, eu não implementei toda a classe para não deixar o post muito grande. Apenas os métodos Gateway::styles e Gateway::scripts foram implementados, porém você pode implementar quantos métodos quiser, inclusive um outro que você provavelmente irá utilizar que é o Gateway::images que irá carregar suas imagens. Espero que o código abaixo o ajude, ele deverá ficar junto com o seu .htaccess na raiz do seu projeto: <?php /** * Interpreta a querystring e distribui as requisições */ abstract class Gateway { /** * Pasta de imagens relativa a localização do Gateway */ const FOLDER_IMG = "images"; /** * Pasta de scripts relativa a localização do Gateway */ const FOLDER_JS = "js"; /** * Pasta de estilos relativa a localização do Gateway */ const FOLDER_CSS = "css"; /** * Pasta onde o Gateway está localizado * @var string */ static public $document_root; /** * Iniciamos o gateway, que irá interpretar a querystring, separar os componentes e distribuir as requisições * conforme necessário. */ static public function start(){ $argv = array(); self::$document_root = getcwd(); /** * Definindo as regras de localização, dinheiro, data e outros para português do Brasil */ setlocale( LC_ALL , 'pt_br' ); date_default_timezone_set( "America/Sao_Paulo" ); /** * Verificamos a existência de algum argumento passado na querystring */ if ( isset( $_REQUEST[ "querystring" ] ) ){ if ( !empty( $_REQUEST[ "querystring" ] ) ){ $mtc = array(); if ( preg_match_all( "/((?:\\/)([^\\/]*))/" , $_REQUEST[ "querystring" ] , $mtc ) ){ $argv = $mtc[ 2 ]; } } unset( $_REQUEST[ "querystring" ] ); } /** * Verificamos se o primeiro argumento passado é um método existente em Gateway, se for então chamamos * o método passando o restante da matriz de argumentos como parâmetro e então interrompemos a execução * da aplicação. */ if ( isset( $argv[ 0 ] ) && method_exists( "Gateway" , $argv[ 0 ] ) ){ $method = array_shift( $argv ); /** * Iniciamos a saída buferizada */ ob_start(); /** * Aqui tentamos chamar o método de Gateway requerido, é importante que qualquer método chamado aqui * retorne TRUE se a requisição for bem sucedida, se for retornado qualquer coisa diferente de TRUE * então um HTTP 400 será enviado para o browser. */ try { $ret = call_user_func_array( array( "Gateway" , $method ) , array( count( $argv ) , $argv ) ); if ( ( gettype( $ret ) != "boolean" ) || !$ret ){ header( "HTTP/1.1 400 Bad Request" ); ob_clean(); } else { /** * Enviamos o conteúdo da chamada para o browser */ ob_end_flush(); } } catch ( Exception $e ){ header( "HTTP/1.1 502 Bad Gateway" ); ob_clean(); } die; } else { /** * Verificamos se existe uma página definida */ if ( count( $argv ) ){ $pagina = array_shift( $argv ); /** * Esse loop é para garantir que o usuário não utilize um // para nos confundir */ while ( !strlen( $pagina ) && count( $argv ) ) $pagina = array_shift( $argv ); if ( !empty( $pagina ) ) $_REQUEST[ "pagina" ] = $_GET[ "pagina" ] = $pagina; } /** * Verificamos se existe uma categoria definida */ if ( count( $argv ) ){ $categoria = array_shift( $argv ); /** * Esse loop é para garantir que o usuário não utilize um // para nos confundir */ while ( !strlen( $categoria) && count( $argv ) ) $categoria = array_shift( $argv ); if ( !empty( $categoria ) ) $_REQUEST[ "categoria" ] = $_GET[ "categoria" ] = $categoria; } /** * Se sobrou algum item na nossa matriz de argumentos então passamos para as variáveis globais * $_GET e $_REQUEST */ if ( count( $argv ) ){ $_REQUEST[ "argv" ] = $_GET[ "argv" ] = $argv; $_REQUEST[ "argc" ] = $_GET[ "argc" ] = count( $argv ); } } } /** * Recupera o conteúdo de um ou mais arquivos * * @param integer $argc Número de itens na matriz de arquivos * @param array $argv Matriz conténdo os arquivos * @param string $base_dir A pasta onde serão procurados os arquivos * @param integer $mtime Receberá a maior data de modificação dos arquivos da lista * @param string $content Receberá o conteúdo da lista de arquivos * @return boolean TRUE se tudo correr bem */ static private function getFilesContent( $argc , $argv , $base_dir , &$mtime , &$content ){ $ret = true; $mtime = 0; $content = ""; /** * Percorremos a matriz $argv e verificamos a existência de cada um dos arquivos solicitados. * Se apenas um arquivo da lista não existir, todo o processo é abortado e um Bad Request é * devolvido ao usuário. */ for ( $i = 0; $i < $argc; $i++ ){ $name = basename( $argv[ $i ] ); /** * Verificamos se o arquivo existe */ if ( file_exists( ( $file = sprintf( "%s/%s" , $base_dir , $name ) ) ) ){ /** * Abrimos o arquivo para podermos lê-lo */ $fh = fopen( $file , "r" ); /** * Verificamos a data de modificação do arquivo */ if ( ( $tempmtime = filemtime( $file ) ) > $mtime ) $mtime = $tempmtime; /** * Se já tivermos algum conteúdo então adicionamos uma quebra de linha para evitar * que o conteúdo de um arquivo comece sobre o fim do arquivo anterior */ if ( !empty( $content ) ) $content .= "\r\n"; /** * Pegamos o conteúdo do arquivo atual */ while ( ( $part = fread( $fh , 32767 ) ) ) $content .= $part; /** * Fechamos o arquivo */ fclose( $fh ); } else { /** * O arquivo solicitado não existe, abortamos a processo */ $ret = false; break; } } return( $ret ); } /** * Devolve as folhas de estilo que o usuário requisitou * * @param integer $argc O total de folhas de estilo requisitadas * @param array $argv Matriz contento o nome do arquivo de cada folha de estilo * @return boolean TRUE se for possível carregar as folhas de estilo requisitadas */ static private function Styles( $argc , $argv ){ $css_folder = sprintf( "%s/%s" , self::$document_root , self::FOLDER_CSS ); $content = ""; $mtime = 0; $ret = self::getFilesContent( $argc , $argv , $css_folder , $mtime , $content ); /** * Verificamos se tudo correu bem */ if ( $ret ){ /** * Ok, tudo correu bem. * Verificamos se temos algum conteúdo, se tivermos então montamos os cabeçalhos e enviamos * o conteúdo para o usuário com um HTTP 200. * Se não tivermos nenhum conteúdo então enviamos apenas um HTTP 204. */ if ( ( $content_length = strlen( $content ) ) ){ header( "HTTP/1.1 200 Ok" ); header( sprintf( "Date: %s" , gmstrftime( "%a, %d %b %Y %H:%M:%S %Z" , time() ) ) ); header( "Content-Type: text/css" ); header( sprintf( "Content-Length: %d" , $content_length ) ); header( "Expires: Wed 1 Dec 2010 00:00:00 GMT" ); header( sprintf( "Last-Modified: %s" , gmstrftime( "%a, %d %b %Y %H:%M:%S %Z" , $mtime ) ) ); header( "Etag: " ); header( "Connection: Close" ); /** * Enviamos o conteúdo para o usuário */ print( $content ); } else { header( "HTTP/1.1 204 No Content" ); } } return( $ret ); } /** * Devolve os scripts que o usuário requisitou * * @param integer $argc O total de scripts requisitados * @param array $argv Matriz contento o nome do arquivo de cada script * @return boolean TRUE se for possível carregar os scripts requisitados */ static private function Scripts( $argc , $argv ){ $js_folder = sprintf( "%s/%s" , self::$document_root , self::FOLDER_JS ); $content = ""; $mtime = 0; $ret = self::getFilesContent( $argc , $argv , $js_folder , $mtime , $content ); /** * Verificamos se tudo correu bem */ if ( $ret ){ /** * Ok, tudo correu bem. * Verificamos se temos algum conteúdo, se tivermos então montamos os cabeçalhos e enviamos * o conteúdo para o usuário com um HTTP 200. * Se não tivermos nenhum conteúdo então enviamos apenas um HTTP 204. */ if ( ( $content_length = strlen( $content ) ) ){ header( "HTTP/1.1 200 Ok" ); header( sprintf( "Date: %s" , gmstrftime( "%a, %d %b %Y %H:%M:%S %Z" , time() ) ) ); header( "Content-Type: text/javascript" ); header( sprintf( "Content-Length: %d" , $content_length ) ); header( "Expires: Wed 1 Dec 2010 00:00:00 GMT" ); header( sprintf( "Last-Modified: %s" , gmstrftime( "%a, %d %b %Y %H:%M:%S %Z" , $mtime ) ) ); header( "Etag: " ); header( "Connection: Close" ); /** * Enviamos o conteúdo para o usuário */ print( $content ); } else { header( "HTTP/1.1 204 No Content" ); } } return( $ret ); } } Gateway::start(); ?> []'s J. Neto
×
×
  • Criar Novo...