servidor - ¿Cómo subir archivos con PHP y Zend Framework?
subir archivos a servidor remoto php (3)
Estoy usando Zend Framework 1.9.6. Creo que lo tengo bastante claro, excepto por el final. Esto es lo que tengo hasta ahora:
Formar:
<?php
class Default_Form_UploadFile extends Zend_Form
{
public function init()
{
$this->setAttrib(''enctype'', ''multipart/form-data'');
$this->setMethod(''post'');
$description = new Zend_Form_Element_Text(''description'');
$description->setLabel(''Description'')
->setRequired(true)
->addValidator(''NotEmpty'');
$this->addElement($description);
$file = new Zend_Form_Element_File(''file'');
$file->setLabel(''File to upload:'')
->setRequired(true)
->addValidator(''NotEmpty'')
->addValidator(''Count'', false, 1);
$this->addElement($file);
$this->addElement(''submit'', ''submit'', array(
''label'' => ''Upload'',
''ignore'' => true
));
}
}
Controlador:
public function uploadfileAction()
{
$form = new Default_Form_UploadFile();
$form->setAction($this->view->url());
$request = $this->getRequest();
if (!$request->isPost()) {
$this->view->form = $form;
return;
}
if (!$form->isValid($request->getPost())) {
$this->view->form = $form;
return;
}
try {
$form->file->receive();
//upload complete!
//...what now?
$location = $form->file->getFileName();
var_dump($form->file->getFileInfo());
} catch (Exception $exception) {
//error uploading file
$this->view->form = $form;
}
}
¿Ahora qué hago con el archivo? Se ha subido al directorio my /tmp
de forma predeterminada. Obviamente, no es donde quiero guardarlo. Quiero que los usuarios de mi aplicación puedan descargarlo. Entonces, estoy pensando que eso significa que necesito mover el archivo cargado al directorio público de mi aplicación y almacenar el nombre del archivo en la base de datos para poder mostrarlo como una url.
O configure esto como el directorio de carga en primer lugar (aunque me encontré con errores al intentar hacer eso antes).
¿Ha trabajado anteriormente con archivos cargados? ¿Cuál es el siguiente paso que debo tomar?
Solución:
Decidí poner los archivos cargados en data/uploads
(que es un enlace de Sym a un directorio fuera de mi aplicación, para poder acceder a todas las versiones de mi aplicación).
# /public/index.php
# Define path to uploads directory
defined(''APPLICATION_UPLOADS_DIR'')
|| define(''APPLICATION_UPLOADS_DIR'', realpath(dirname(__FILE__) . ''/../data/uploads''));
# /application/forms/UploadFile.php
# Set the file destination on the element in the form
$file = new Zend_Form_Element_File(''file'');
$file->setDestination(APPLICATION_UPLOADS_DIR);
# /application/controllers/MyController.php
# After the form has been validated...
# Rename the file to something unique so it cannot be overwritten with a file of the same name
$originalFilename = pathinfo($form->file->getFileName());
$newFilename = ''file-'' . uniqid() . ''.'' . $originalFilename[''extension''];
$form->file->addFilter(''Rename'', $newFilename);
try {
$form->file->receive();
//upload complete!
# Save a display filename (the original) and the actual filename, so it can be retrieved later
$file = new Default_Model_File();
$file->setDisplayFilename($originalFilename[''basename''])
->setActualFilename($newFilename)
->setMimeType($form->file->getMimeType())
->setDescription($form->description->getValue());
$file->save();
} catch (Exception $e) {
//error
}
Si moviera el archivo a un directorio público, cualquiera podría enviar un enlace a ese archivo a cualquier otra persona y usted no tiene control sobre quién tiene acceso al archivo.
En su lugar, podría almacenar el archivo en el DB como un bloque largo y luego usar Zend Framework para proporcionar a los usuarios acceso al archivo a través de un controlador / acción. Esto le permitiría ajustar su propia autenticación y la lógica de permisos de usuario en torno al acceso a los archivos.
Necesitará obtener el archivo del directorio / tmp para guardarlo en el archivo db:
// I think you get the file name and path like this:
$data = $form->getValues(); // this makes it so you don''t have to call receive()
$fileName = $data->file->tmp_name; // includes path
$file = file_get_contents($fileName);
// now save it to the database. you can get the mime type and other
// data about the file from $data->file. Debug or dump $data to see
// what else is in there
Su acción en el controlador para visualizar tendría su lógica de autorización y luego cargaría la fila desde la base de datos:
// is user allowed to continue?
if (!AuthenticationUtil::isAllowed()) {
$this->_redirect("/error");
}
// load from db
$fileRow = FileUtil::getFileFromDb($id); // don''t know what your db implementation is
$this->view->fileName = $fileRow->name;
$this->view->fileNameSuffix = $fileRow->suffix;
$this->view->fileMimeType = $fileRow->mime_type;
$this->view->file = $fileRow->file;
Luego en la vista:
<?php
header("Content-Disposition: attachment; filename=".$this->fileName.".".$this->fileNameSuffix);
header(''Content-type: ".$this->fileMimeType."'');
echo $this->file;
?>
$this->setAction(''/example/upload'')->setEnctype(''multipart/form-data'');
$photo = new Zend_Form_Element_File(''photo'');
$photo->setLabel(''Photo:'')->setDestination(APPLICATION_PATH ."/../public/tmp/upload");
$this->addElement($photo);
De forma predeterminada, los archivos se cargan en el directorio temporal del sistema, lo que significa que usted podrá:
- use
move_uploaded_file
para mover los archivos a otro lugar, - o configure el directorio al que Zend Framework debería mover los archivos; su elemento de formulario debe tener un método de
setDestination
que pueda usarse para eso.
Para el segundo punto, hay un ejemplo en el manual :
$element = new Zend_Form_Element_File(''foo'');
$element->setLabel(''Upload an image:'')
->setDestination(''/var/www/upload'')
->setValueDisabled(true);
(Pero lea esa página: hay otras informaciones útiles)