Avançar para a área de conteúdo

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

A primeira vez que acessar o developerWorks, um perfil será criado para você. Informações do seu perfil (tais como: nome, país / região, e empresa) estarão disponíveis ao público, que poderá acompanhar qualquer conteúdo que você publicar. Seu perfil no developerWorks pode ser atualizado a qualquer momento.

Todas as informações enviadas são seguras.

  • Fechar [x]

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

Todas as informações enviadas são seguras.

  • Fechar [x]

Aprendendo PHP, Parte 2: Fazer Upload dos Arquivos e Usar XML para Armazenar e Exibir Informações de Arquivo

Tyler Anderson, Engineer, Backstop Media
Tyler's photo
Tyler Anderson graduou-se em ciência da computação em 2004 e concluiu seu mestrado em engenharia elétrica e da computação em 2005 na Brigham Young University. Ele trabalhou para a Stexar Corp. como engenheiro de projetos, em pesquisa e desenvolvimento, de maio de 2005 a agosto de 2006. Desde sua descoberta pela Backstop Media LLC no início de 2005, ele tem escrito e codificado muitos artigos e tutoriais para a IBM developerWorks e DevX.com.
Nicholas Chase, Web Developer, Author, Consultant
Nicholas Chase esteve envolvido no desenvolvimento de Web sites para empresas como a Lucent Technologies, a Sun Microsystems, a Oracle e a Tampa Bay Buccaneers. Nick é professor de física do ensino médio, gerente de instalação de lixo radioativo de nível baixo, editor de revista on-line de ficção científica, engenheiro de multimídia, instrutor Oracle e o Executivo Chefe em Tecnologia de uma empresa de comunicações interativas. Ele é o autor de diversos livros, incluindo XML Primer Plus (Sams).

Resumo:  Este tutorial é a Parte 2 de uma série "Aprendendo PHP" em três partes que ensina como usar PHP através da construção de uma aplicação simples de fluxo de trabalho. Faça este tutorial se tiver um entendimento básico de PHP e quiser aprender sobre como fazer upload de arquivos a partir do navegador, sessões ou usando PHP para processar XML.

Visualizar mais conteúdo nesta série

Data:  21/Jun/2005
Nível:  Intermediário

Atividade:  8008 visualizações

Funções

Criar o Documento DOM

Primeiro, cria-se um objeto Document DOM que pode ser usado para manipular os dados. Abra o arquivo scripts.txt e inclua o seguinte código:

...
   define(UPLOADEDFILES, "/var/www/hidden/");

   function save_document_info($fileInfo){

       $doc = new DOMDocument('1.0');

   }
?>

O processo real de criação de um objeto Document , neste caso chamado de $doc, é direto. A classe DOMDocument faz parte do núcleo do PHP V5. Esse objeto é usado para executar a maior parte de suas ações nos dados.


Criar um Elemento

Agora, que há um Document funcional, é possível usá-lo para criar o elemento principal ou raiz do documento:

...
function save_document_info($fileInfo){

   $doc = new DOMDocument('1.0');
   $root = $doc->createElement('workflow');
   $doc->appendChild($root);

}
...

Aqui, indica-se ao objeto $doc que deve criar um novo elemento e retorná-lo à variável $root . Indica-se então a Document que deve incluir esse elemento como seu filho.

Mas o que acontece se esse documento for salvo como um arquivo?


Salvar o Documento em um Arquivo

Uma vantagem de usar PHP para processar seu XML é que PHP fornece uma maneira fácil de salvar o conteúdo de um Document em um arquivo. (Acredite se quiser, mas nem sempre é tão fácil assim.) Para ver o que está realmente sendo gerado, inclua o código a seguir em save_document_info():

...
function save_document_info($fileInfo){

   $doc = new DOMDocument('1.0');
   $root = $doc->createElement('workflow');
   $doc->appendChild($root);

   $doc->save(UPLOADEDFILES."docinfo.xml");

}
...

A constante UPLOADEDFILES foi definida anteriormente, portanto, pode simplesmente seguir em frente e fazer referência a ela agora, colocando o novo arquivo no mesmo diretório. Se agora fizer upload de um arquivo através do navegador, o arquivo docinfo.xml deve ter a seguinte aparência:n

<?xml version="1.0"?>
<workflow/>

Não se preocupe com a primeira linha, é a declaração XML e é padrão, mas é opcional (na maioria dos casos).

Observe que seu elemento foi salvo, mas como não incluiu ainda no mesmo nenhum filho nem conteúdo realmente, é gravado como um elemento vazio.

Agora, vamos incluir um elemento mais complicado.


Criar Atributos

Inicie a inclusão de informações reais no arquivo. Um arquivo já foi criado para testar a etapa anterior, mas até salvar completamente as informações do primeiro arquivo, pode-se supor que ainda esteja criando o arquivo docinfo.xml.

Inicie criando o elemento statistics :

...
function save_document_info($fileInfo){

   $doc = new DOMDocument('1.0');
   $root = $doc->createElement('workflow');
   $doc->appendChild($root);

   $statistics = $doc->createElement("statistics");
   $statistics->setAttribute("total", "1");
   $statistics->setAttribute("approved", "0");
   $root->appendChild($statistics);

   $doc->save(UPLOADEDFILES."docinfo.xml");

}
...

Observe que Document será usado para criar o novo elemento, desta vez chamado de statistics. O Document age como uma "fábrica" para a maioria de seus objetos.

Quando tiver o objeto Element , $statistics, é possível usar suas funções integradas para configurar dois atributos: total e approved. Após fazer isso, deve incluir esse elemento como um filho de $root, em vez de um filho de $doc. Se salvar o arquivo, poderá ver a diferença:

<?xml version="1.0">
<workflow><statistics total="1" approved="0"/></workflow>

Perceberá duas coisas aqui. Primeiro, observe que o elemento statistics é filho do elemento workflow . Observe também que não há nenhum espaço em branco irrelevante aqui. O elemento statistics é o primeiro filho do workflow.

Agora, vamos dar uma olhada em incluir informações reais.


Criar o Elemento de Informações do Arquivo

Agora, é possível seguinte em frente e criar as informações reais do documento. O processo usa as técnicas que você acabou de aprender.

...
function save_document_info($fileInfo){

   $doc = new DOMDocument('1.0');
   $root = $doc->createElement('workflow');
   $doc->appendChild($root);

   $statistics = $doc->createElement("statistics");
   $statistics->setAttribute("total", "1");
   $statistics->setAttribute("approved", "0");
   $root->appendChild($statistics);

   $filename = $fileInfo['name'];
   $filetype = $fileInfo['type'];
   $filesize = $fileInfo['size'];

   $fileInfo = $doc->createElement("fileInfo");

   $fileInfo->setAttribute("status", "pending");
   $fileInfo->setAttribute("submittedBy", $_SESSION["username"]);

   $approvedBy = $doc->createElement("approvedBy");

   $fileName = $doc->createElement("fileName");
   $fileNameText = $doc->createTextNode($filename);
   $fileName->appendChild($fileNameText);

   $location = $doc->createElement("location");
   $locationText = $doc->createTextNode(UPLOADEDFILES);
   $location->appendChild($locationText);

   $type = $doc->createElement("fileType");
   $typeText = $doc->createTextNode($filetype);
   $type->appendChild($typeText);

   $size = $doc->createElement("size");
   $sizeText = $doc->createTextNode($filesize);
   $size->appendChild($sizeText);

   $fileInfo->appendChild($approvedBy);
   $fileInfo->appendChild($fileName);
   $fileInfo->appendChild($location);
   $fileInfo->appendChild($type);
   $fileInfo->appendChild($size);

   $root->appendChild($fileInfo);

   $doc->save(UPLOADEDFILES."docinfo.xml");

}
...

Apesar de haver muito código aqui, muito pouco é novo. Primeiro, extrai-se as informações reais sobre o arquivo das informações passadas para a função. Cria-se então o elemento fileInfo que conterá todas as informações que estão sendo incluídas. Configura-se os atributos status e submittedBy nesse elemento e verifica-se então a criação de seus elementos.

O elemento approvedBy é fácil. Ainda não foi aprovado, portanto, isso permanecerá vazio. O elemento fileName , por outro lado, é um pouco mais difícil, pois é necessário incluir um filho de texto no mesmo. Felizmente, isso também é bem direto. O elemento é criado, então, Document é usado para criar o novo nó de texto que tem como seu conteúdo o nome do arquivo. Pode-se então incluir esse nó de texto como filho do elemento fileName .

É possível progredir dessa forma, criando todos os elementos que, eventualmente, serão filhos de fileInfo. Após ter concluído, todos são anexados como filhos do elemento fileInfo . Por fim, o próprio elemento fileInfo é incluído no elemento-raiz, workflow.

Os resultados, com espaçamento incluído por questão de clareza, têm aparência semelhante ao seguinte:

<?xml version="1.0"?>
<workflow>
   <statistics total="1" approved="0"/>
   <fileInfo status="pending" submittedBy="roadnick">
      <approvedBy/>
      <fileName>signed.pem</fileName>
      <location>/var/www/hidden/</location>
      <fileType>application/octet-stream</fileType>
      <size>2754</size>
   </fileInfo>
</workflow>

É claro que não é possível continuar sobrescrevendo o arquivo de informações toda vez que alguém faz upload de um documento, portanto, em seguida, verá como é trabalhar com uma estrutura existente.


Inserindo um Documento Existente

Agora que já sabe como incluir informações no arquivo, é necessário verificar como trabalhar com o arquivo em uploads subsequentes. Primeiro, é necessário ver se o arquivo já existe, então agir conforme necessário:

...
function save_document_info($fileInfo){

   $xmlfile = UPLOADEDFILES."docinfo.xml";

   if(is_file($xmlfile)){
      $doc = DOMDocument::load($xmlfile);
      $workflowElements = $doc->getElementsByTagName("workflow");
      $root = $workflowElements->item(0);
   } else{

      $doc = new DOMDocument('1.0');
      $root = $doc->createElement('workflow');
      $doc->appendChild($root);

      $statistics = $doc->createElement("statistics");
      $statistics->setAttribute("total", "1");
      $statistics->setAttribute("approved", "0");
      $root->appendChild($statistics);
   }

   $filename = $fileInfo['name'];
   $filetype = $fileInfo['type'];
   $filesize = $fileInfo['size'];

   $fileInfo = $doc->createElement("fileInfo");
...
   $fileInfo->appendChild($size);

   $root->appendChild($fileInfo);

   $doc->save($xmlfile);

}

Iniciando na parte superior, cria-se uma varável para representar o local do arquivo, já que agora será feita referência a ele em mais de um local. Em seguida, verifica-se se esse arquivo já existe. Se existir, a função load() é chamada, em vez de cria-se um novo objeto.

Essa função estática -- sobre a qual falaremos mais na Parte 3 desta série; por ora, entenda que são funções que podem ser chamadas a partir da classe, em vez de a partir de um objeto -- retorna um objeto Document que já está preenchido com todos os elementos, texto, etc., representados no arquivo.

Quando tiver o objeto Document , o elemento workflow será necessário, pois, no final, será necessário incluir o novo elemento fileInfo no mesmo. Obtém-se o elemento workflow recuperando primeiro uma lista de todos os elementos do documento chamado workflow e então selecionando o primeiro da lista.

A partir de então, é possível simplesmente incluir o novo elemento fileInfo e ele aparecerá após o original. Novamente, com espaço incluído por questão de clareza:

<?xml version="1.0"?>
<workflow>
   <statistics total="1" approved="0"/>
   <fileInfo status="pending" submittedBy="roadnick">
      ...
   </fileInfo>
   <fileInfo status="pending" submittedBy="roadnick">
      <approvedBy/>
      <fileName>timeone.jpg</fileName>
      <location>/var/www/hidden/</location>
      <fileType>image/jpeg</fileType>
      <size>2020</size>
   </fileInfo>
</workflow>

E statistics? Obviamente, não estão mais corretos. Isso precisará ser resolvido.


Manipulando Dados Existentes

Além de incluir informações no documento, é possível alterar informações que já estão lá. Por exemplo, é possível atualizar o atributo total no elemento statistics :

...
   if(is_file($xmlfile)){
      $doc = DOMDocument::load($xmlfile);
      $workflowElements = $doc->getElementsByTagName("workflow");
      $root = $workflowElements->item(0);

      $statistics = $root->getElementsByTagName("statistics")->item(0);
      $total = $statistics->getAttribute("total");
      $statistics->setAttribute("total", $total + 1);

   } else{
...

Primeiramente, obtém-se uma referência ao elemento statistics existente da mesma forma que obteve-se do elemento workflow existente, apenas combina-se ambas as etapas em uma. Quando tiver uma referência para o elemento, é possível obter o valor atual do atributo total usando a função getAttribute() . Pode-se usar então esse valor para fornecer um valor atualizado para o atributo total usando setAttribute().

Os resultados são os que podem ser esperados, desta vez, sem espaços incluídos:

<?xml version="1.0"?>
<workflow><statistics total="2" approved="0"/><fileInfo status="pending"
submittedBy="roadnick">...

Agora que já sabe como usar o DOM para criar o arquivo, vamos dar uma olhada em como lê-lo novamente usando outra API XL, SAX.

5 de 9 | Anterior | Próximo

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Software livre
ArticleID=397415
TutorialTitle=Aprendendo PHP, Parte 2: Fazer Upload dos Arquivos e Usar XML para Armazenar e Exibir Informações de Arquivo
publish-date=06212005
author1-email=tyleranderson5@yahoo.com
author1-email-cc=
author2-email=ibmquestions@nicholaschase.com
author2-email-cc=