Hosting de imágenes sin base de datos mysql-sqlite ni archivos en carpetas

Iniciado por WHK, 23 Mayo 2011, 03:33 AM

0 Miembros y 1 Visitante están viendo este tema.

WHK

Actualmente algunos hosting dan espacio ilimitado pero un detalle que nunca nos fijamos es que cuando lo compramos vemos en el cpanel un indicador el cual nos indica el límite de número de archivos   :xD y eso en parte nos hecha por tierra todo el plan de hacer cosas como hosting de archivos, imágenes, etc.

Otra alternativa era alojar los archivos dentro de la base de datos codificados en base64 pero eso causaría una sobrecarga significativa si las visitas son numerosas.

Por lo tanto ideé una forma de alojar nuestros archivos de la siguiente manera:

Lo que vamos a hacer es crear un solo archivo como base de datos y le vamos a ir agregando al final todos los archivos de forma binaria, uno tras otro y de esta forma podremos alojar todos nuestros archivos en uno solo.

Algunos dirán que si la base de datos es enorme tendremos problemas de memoria,... pues no debido a que el script que haremos tomará el archivo y posicionará el puntero en el bite correspondiente a la imágen y luego obtendrá la cantidad de bites necesarios y luego finalizará.
Esto lo he probado con un iso de casi 3GB, he descargado solo 1MB a partir del bite que está posicionado en 500MB hasta 1MB después y el script anda rapidisimo, en menos de 0,2 segundos lo obtiene completamente y te lo entrega sin problemas ni uso excesivo de memoria ya que no cargará los 3GB sino solo 1MB.

Cómo límite vamos a configurar nuestro script para que se pueda subir y descargar archivos de hasta 2MB.

Código (php) [Seleccionar]
<?php
/* Default config */
$sys = array(
'db' => '.ht_dbimages'/* Database */
'self_script' => (isset($_SERVER['HTTPS']) == true 'https' 'http' '://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']),
'start' => 0/* Bite start */
'length' => 0/* Bites length */
'extension' => '.dat'/* File extension */
'max_length' => 2000000/* Max upload/download file (2MB) */
'finish_poiner' => 0,
'finish_length' => 0,
'finish_extension' => 'jpg',
'totalsizedb' => 0,
'err' => false,
'headerdb' => "DBIMG\x00\x01"
);
/* Re-config... */
if(!file_exists($sys['db']))
file_put_contents($sys['db'], $sys['headerdb']);
$sys['totalsizedb'] = filesize($sys['db']);

if(
$_FILES){
/* Manage errors */
if((int)$_FILES['img']['size'] > (int)$sys['max_length'])
$sys['err'] = 'El archivo es demasiado grande.';
if(!exif_imagetype($_FILES['img']['tmp_name']))
$sys['err'] = 'El archivo no es una imágen.';
/* Save file */
if(!$sys['err']){
$sys['finish_pointer'] = (int)$sys['totalsizedb'];
$sys['finish_length'] filesize($_FILES['img']['tmp_name']);
$sys['finish_extension'] explode('.'$_FILES['img']['name']);
$sys['finish_extension'] substr($sys['finish_extension'][count($sys['finish_extension']) - 1], 05);
file_put_contents($sys['db'], file_get_contents($_FILES['img']['tmp_name']), FILE_APPEND LOCK_EX);
}

}elseif(isset(
$_GET['data']) and (strlen($_GET['data']) > 0)){
/* Split data */
$data $_GET['data'];
if(str_replace('/'''$data) != $data){
$data explode('/'$data);
$data $data[count($data) - 1];
}
$data explode('_'$data);
$sys['start'] = (int)$data[0];
$data explode('.'$data[1]);
$sys['length'] = (int)$data[0];
$sys['extension'] = $data[count($data) - 1];
/* Manage errors */
if($sys['length'] > $sys['max_length'])
$sys['err'] = 'El archivo es demasiado grande.';
if($sys['start'] < 1)
$sys['err'] = 'El archivo no existe.';
if(($sys['start'] + $sys['length']) > $sys['totalsizedb'])
$sys['err'] = 'El archivo no existe.';
$tmpf tempnam(0'');
file_put_contents($tmpffile_get_contents($sys['db'], NULLNULL$sys['start'], $sys['length']));
if(!exif_imagetype($tmpf))
$sys['err'] = 'El archivo no es una imágen.';
/* Get file */
if(!$sys['err']){
header('Content-Type: image/'.substr($sys['extension'], 05));
header('Content-Length: '.(int)$sys['length']);
/* MAX Cache */
header('Last-Modified: Tue, 03 Jul 2001 06:00:00 GMT');
header('Expires: Tue, 03 Jul 2500 06:00:00 GMT');
echo file_get_contents($tmpf);
exit;
}

}
?>


<?php if($sys['err']){ ?>
Error: <?php echo $sys['err']; ?><hr />
<?php }elseif((int)$sys['finish_pointer'] > 0){ ?>
File saved:
<a target="_blank" href="<?php echo ($outfile dirname($sys['self_script']).'/'.(int)$sys['finish_pointer'].'_'.(int)$sys['finish_length'].'.'.$sys['finish_extension']); ?>">
<?php echo $outfile?>
</a><hr />
<?php ?>
<form action="<?php echo $sys['self_script']; ?>" method="post" enctype="multipart/form-data">
Image: <input type="file" name="img" /> <input type="submit" value="Upload" />
</form>


Ahora el archivo subido nos quedará así:
/500_10.jpg
donde 500 es el bite de inicio, 10 es el tamaño de bites y jpg es la extensión.

Para interpretar esto necesitamos un htaccess:
# MiniHostingIMG V1.0 by DrawCoders
Options -Indexes
ErrorDocument 404 "El archivo no existe <a href='javascript:history.go(-1);'>Volver</a>"
RewriteEngine on
RewriteCond %{REQUEST_URI} !(.*)index.php$
RewriteRule ^(.*)$ index.php?data=$1


Si se fijan el error 404 le puse el contenido directo (que ustedes pueden modificar o poner una url) y el index en cualquier parte para que no de problemas al poner nuestro sistema en un subdirectorio y no tengamos que editar todo manualmente.

Recuerden que deben dar permisos de escritura a la base de datos.
El nombre de la base de datos le puse que comenzara en .ht... porque por defecto el servidor apache impide la visualización directa de estos archivos porque supuestamente son de configuración.

Ejemplo de prueba momentaneo:
http://www.webcomparte.com/lab/hotingimg/




Además le puse un header para el caché, de esta forma la gente cargará una sola ves la imágen impidiendo la sobrecarga.

El diseño se lo ponen ustedes a su antojo.
Cualquier duda me la escriben.

Saludos.

Nakp

sabes que es lo que me sorprende? ademas de la idea que tuviste para alojar las imagenes.. bastante ingeniosa por cierto... estas identando el codigo!!!! y muchos no creen en el fin del mundo :¬¬ señores!! se acerca!!!
Ojo por ojo, y el mundo acabará ciego.

madpitbull_99

Es buena idea y muy bueno el script, acabo de probarlo:



En algunos hostings compartidos he encontrado límite por archivo de 3 y 4 GB, por lo que, al llegar a ese tope podrías tener problemas, en Linux se mira con ulimit -a.


CitarOtra alternativa era alojar los archivos dentro de la base de datos codificados en base64 pero eso causaría una sobrecarga significativa si las visitas son numerosas.

Esto es poco recomendable por la mayoría de los programadores, en la base de datos solo se guarda la ruta absoluta hacia la imagen.



«Si quieres la paz prepárate para la guerra» Flavius Vegetius


[Taller]Instalación/Configuración y Teoría de Servicios en Red