PHP-Hispano.net Comunidad hispana de desarrollo web

Contacto | #php_para_torpes | Enlázanos | ¿Quiénes somos?

4290 usuarios Online (0)

Darse de alta en la web | Recuperar password   
Inicio / Foros / PHP / problemas con el renombrado en una base de datos

problemas con el renombrado en una base de datos

13 respuestas 528 visitas Categoría PHP

problemas con el renombrado en una base de datos

Avatar de yuber
* * * * * * *

(Nivel 1 - 30 posts)

#0 Offline yuber Usuario 26 may 10
Hola, tengo un codigo para poder introducir varias imagenes a la vez en

una base de datos que funciona bien, pero lo que quiero es que cuando

se vayan a insertar se renombren tanto en en la base de datos como los

propios ficheros y ademas les ponga un numero en funcion de la

insercion.





Mi base de datos es de pesronajes de todo tipo y lo que busco es lo siguiente.

Imaginemos que tenemos esta imagen 3345345345345345.jpg y corresponde al personaje Hannibal



Pues bien la idea es que al insertarla en la base de datos entre asi



Hannibal_001.jpg



Si insertaramos otra de Hannibal entraria



Hannibal_002.jpg



y asi sucesivamente, he conseguido que al entrar en la base de datos

entre ya renombrada como yo quiero, pero lo que no consigo es que al

mover las imagenes a la carpeta se renombren igual que en la base de

datos.



Este es mi codigo.







for ($i = 0; $i < $totalimagenes; $i++){



    $imagenespequenas=$_FILES["imagenespequenas"]["name"][$i];



    echo $imagenespequenas;



         $tmp = $_FILES["imagenespequenas"]["tmp_name"][$i];



         



 if($imagenespequenas!="")



{          //esto se hace para dividir las imagenes pequeñas en nombre

y extension y asi poder agregar la extension al renombrado



        $partes=explode(".",$imagenespequenas);



//variable para renombrar en funcion del personaje



        $renomdestino=$nompersonaje.'_'.$i.'.'.$partes[1];



        rename($imagenespequenas,$renomdestino);



  



        $sql="INSERT INTO imagenes (codpersonaje_imagen, nombre_imagen) VALUES ('".$codpersonaje."','".$renomdestino."') ";



   echo '<br />';
 
   //MOVIENDO LAS IMAGENES



           move_uploaded_file($tmp,"imagenes/imagenespequenas/".$imagenespequenas);



            echo $sql;



             //$consulta = mysql_query($sql, $conexion);

             



   



}







Al ejecutar este codigo, me suelta este error







Warning: rename(CH91_130_035.jpg,kaori makimura_0.jpg)
[<a rel="nofollow" href="http://localhost/Proyecto_prueba/function.rename">function.rename</a>]:
No error in C:xampphtdocsProyecto_pruebainsercionpersonaje.php on line 77



Y luego esta el otro tema, según este codigo el renombrado autonumerico
lo hace bien al meter el dato en la base de datos, pero solo lo hace
bien cuando insertas un personaje nuevo con sus imagenes, pero si por
cualquier casualidad quieres insertar mas imagenes, empieza el
renombrado nuevamente desde 0 cuando deberia continuar desde el ultimo
numero en que se quedo.



Ejemplo



Insertamos 2 imagenes nuevas para un personaje nuevo



Hannibal01.jpg

Hannibal02.jpg



hasta aqui perfecto, pero si queremos insertar otra imagen mas en ese personaje ya creado, el renombrado quedaria asi

Hannibal01.jpg



cuando deberia ser



Hannibal03.jpg



me he devanado mucho la cabeza y no se me ocurre ningún metodo para conseguir esto

Paralelamente a esto he creado otro codigo para poder introducir ceros en el renombrado en funcion de las cifras que renombren las fotos, pero al fallar el tema del renombrar imagenes a posteriori con el numero siguiente al que se quedo no he podido probarlo,

¿Funcionaria asi?

if(strlen($i)==3)
    {$renomdestino=$nompersonaje.'_'.$i.'.'.$partes[1];}
    elseif(strlen($i)==2)
    {$renomdestino=$nompersonaje.'_0'.$i.'.'.$partes[1];}
    elseif(strlen($i)==1)
    {$renomdestino=$nompersonaje.'_00'.$i.'.'.$partes[1];}

Lo que quiero que haga es que si el renombrado es de una cifra te añada 2 ceros, si es de 2 cifras te añada 1 y si es de 3 que no añada ninguno.

Re: problemas con el renombrado en una base de datos

Avatar de Eloy8857
* * * * * * *

(Nivel 4 - 454 posts)

#1 Offline Eloy8857 Usuario 27 may 10
Por una parte, creo que el rename no funciona porque las rutas que pones no son correctas. Tienes que usar la ruta origen y la ruta destino, y como no lo haces se buscan en el directorio actual de trabajo del script. Y por otra parte, no necesitas rename al moverla con move_uploaded_file. Si te fijas en esa función verás que le dices qué archivo es el que quieres mover, y a dónde (ruta y nombre de archivo) así que le puedes poner el que tú quieras). Por cierto, cuidado con los espacios en el nombre del archivo, que no es algo muy portable (usa str_replace).

Para poner números secuenciales por usuario es demasiado trabajoso para gestionarlo internamente con la BD, sobre todo porque no tiene secuencias independientes de las tablas. Pero puedes hacer dos cosas que se me ocurran:

-Una función en PHP que dado un usuario te dé el número de la última imagen subida.
-Una función MySQL que dado un usuario te dé él número de la última imagen subida.

Si usas MySQL 5.0 o superior y tienes privilegios podrás usar la segunda solución, con CREATE FUNCTION. En cualquiera de los dos casos deberías usar una combinación de SUBSTRING_INDEX para sacar el número (con los 0), algo tipo:


mysql> SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('imagen_test_01.jpg', '.', 1), '_', -1) AS test;
+------+
| test |
+------+
| 01   |
+------+
1 row in set (0.06 sec)



Y también deberás el nombre de imagen como índice único en la BD, para protegerte de concurrencias.

Saludos.

Restless Souls Online: se viene un gran MMORPG

Re: problemas con el renombrado en una base de datos

Avatar de yuber
* * * * * * *

(Nivel 1 - 30 posts)

#2 Offline yuber Usuario 28 may 10
Hola, desconocia francamente que pudises usar el move uploaded como rename, eso me simplifica las cosas, te lo agradezco.

Respecto a lo de los numeros secuenciales, realmente no es que sea que guarde un numero por usuario, la idea es que por ejemplo si tu subes 2 imagenes de nombre

1.jpg
2.jpg

al insertar un nuevo personaje te lo hará perfectamente bien, pero si tu u otro usuario quiere aumentar esas imagenes, independientemente del usuario que sea la siguiente imagen que subas según el codigo que he puesto anteriormente, seguira siendo 1.jpg cuando deberia ser 3.jpg.

La solucion que me comenas de substring me parece demasiado compleja, ¿no hay algún modo de guardar el ultimo numero autonumerico insertado y ponerselo a la variable contador?

Yo pensaba modificar el for, pero claro de hacerlo como yo pienso no funcionaria, por que quedaria tal que asi.


$ultimonumeroinsertado=0;
for ($i = $ultimonumeroinsertado; $i < $totalimagenes; $i++){

$renomdestino=$nompersonaje.'_'.$i.'.'.$partes[1];
rename($imagenespequenas,$renomdestino);
 $ultimonumeroinsertado=$i;
}

pero como digo no funcionaria por que siempre estamos inicializando el ultimonumero a 0, pero llevo un rato pensando y no sé como hacerlo para que solo se inicialize la primera vez y las demas se tome como referencia el ultimo numero insertado

Re: problemas con el renombrado en una base de datos

Avatar de Eloy8857
* * * * * * *

(Nivel 4 - 454 posts)

#3 Offline Eloy8857 Usuario 31 may 10
No he entendido los requisitos de la incrementación de los contadores de imágenes, pero ante el problema de obtener el último usado tienes la consulta que te he puesto. Seguramente tendrás el nombre de la imagen, pero no el número, así que puedes usar LIKE:


<?php
SELECT SUBSTRING_INDEX
(SUBSTRING_INDEX(ruta_imagen'.'1), '_', -1) AS contador FROM imagenes WHERE ruta_imagen LIKE '$ruta_sin_contador%' ORDER BY contador DESC LIMIT 1
?>




Con eso sacarías el último contador usado para una imagen que casa con 'usuario_%' (el % casa con todo), pero si vas a usar _ como separador entre usuario y contador, debes escaparlo con contrabarra al asignarlo a la variable del LIKE porque es un comdín que coincide con cualquier carácter una vez. Casi mejor usa otro char que no permitas en el nombre de usuario, como # o |.
Si la consulta no devuelve resultados pones el contador a 1 y ya está.

Saludos.

Restless Souls Online: se viene un gran MMORPG

Re: problemas con el renombrado en una base de datos

Avatar de yuber
* * * * * * *

(Nivel 1 - 30 posts)

#4 Offline yuber Usuario 31 may 10
Hombre, ahora que miro mas de cerca tu sentencia si que es verdad que puede servir, no entiendo lo del substring_index pero ya lo mirare.

No obstante, de momento no tengo nada en lo que se refiere a usuarios implementados, y de hecho aunque implemente el poder introducir personajes por usuario, no afectará para nada a poder renombrar imagenes, asi que el SELECT se podria hacer perfectamente igual que si no hubiera usuarios.

Pero la duda que viene ahora es que me da la impresion que ese SELECT no funcionaria con el if que puse arriba, es decir este


if(strlen($i)==3)

    {$renomdestino=$nompersonaje.'_'.$i.'.'.$partes[1];}

    elseif(strlen($i)==2)

    {$renomdestino=$nompersonaje.'_0'.$i.'.'.$partes[1];}

    elseif(strlen($i)==1)

    {$renomdestino=$nompersonaje.'_00'.$i.'.'.$partes[1];}

supongo que habria que adaptarlo para que pudiese buscar dependiendo de los ceros ¿me equivoco  
o funcionaria asi también.?

Re: problemas con el renombrado en una base de datos

Avatar de Eloy8857
* * * * * * *

(Nivel 4 - 454 posts)

#5 Offline Eloy8857 Usuario 31 may 10
El SELECT te devolvería también los ceros, así que podría devolver 001, 010 y 100.

Si decides que quieres tener una longitud de 3 dígitos puedes usar sprintf o str_pad y la función lo hará por ti, no necesitas ningún if. Si no hay ninguna imagen (el SELECT no devuelve resultados) asignas 1 al contador y del mismo modo sprintf/str_pad lo hará por ti. Por ejemplo:


<?php
echo sprintf("test %'03d"5);
?>



Saludos.

Restless Souls Online: se viene un gran MMORPG

Re: problemas con el renombrado en una base de datos

Avatar de yuber
* * * * * * *

(Nivel 1 - 30 posts)

#6 Offline yuber Usuario 09 jun 10
Hola de nuevo y perdón por el retraso, no he podido pasarme, he estado examinando y probando tu solucion y si serviria en caso de que todas las imagenes se llamasen igual pero es que la cosa es mucho mas complicada que lo que parece. Imagina que es una base de datos sin que puedan acceder usuarios a ellas, es decir que el tema de usuarios no este implementado por el momento.

La idea es la siguiente tenemos estas imagenes

xx
xa
xb

y sus extensiones(que obviare de momento para ir mas rapido)

luego tenemos estas otras

xc
xd
xe
xj
bien las 3 primeras corresponden al personaje Hannibal
(estas)
xx
xa
xb

las insertamos y con el tema del renombrado y tal quedarian asi

Hannibal_01
Hannibal_02
Hannibal_03
Hannibal_04
y luego hacemos lo mismo con las otras 3 que corresponden al personaje James bond
(estas)
xc
xd
xe
quedarian asi

Jamesbond_01
Jamesbond_02
Jamesbond_03

bien hasta aqui ningún problema, el problema surge cuando queremos insertar mas del mismo personaje u otro, supongamos que queremos insertar 2 de hannibal y una de james bond, pero por este orden
1 de hannibal
1 de james
1 de hannibal


La base de datos tendria todas las imagenes hasta este punto en este orden y como no tengo implementado bien el codigo quedaria asi


Hannibal_01
Hannibal_02
Hannibal_03
Hannibal_04
Jamesbond_01
Jamesbond_02
Jamesbond_03
Hannibal_01
Jamesbond_01
Hannibal_01


Es decir, si te fijas en las 3 ultimas, si las insertas una por una siempre empieza a contabilizar desde 1, por lo que la tercera empezando por abajo estaria sobreescribiendo a la primera empezando por arriba y posteriormente la ultima imagen sobreescribiria a la tercera empezando por abajo, ¿Como seria correcto? si cojiese el valor de la ultima imagen de hannibal, en este caso la 04 y de ahi contando, pero luego hay otro nombre james bond, lo correcto es que la que cogiese para renombrar fuese el ultimo valor de james bond, es decir, la 03, por lo que de hacerlo correctamente estos serian los valores que entrarian en la base de datos y por tanto los valores de los archivos renombrados.


Hannibal_01
Hannibal_02
Hannibal_03
Hannibal_04
Jamesbond_01
Jamesbond_02
Jamesbond_03
Hannibal_05
Jamesbond_04
Hannibal_06

¿Cual es el problema de esto?, identificar los nombres y cual tiene que renombrar, personalmente yo al principio de todo esto no queria hacerlo comparando con la base de datos por esto, por que se puede volver algo desconmunal es imposible establecer una comparacion para miles y miles de pesronajes y que funcione, pero claro, ahora que he visto un poco las tripas de la funcion que me has pasado, me doy cuenta de que es muy dificil hacerlo de otra forma, la cuesiton es como, francamente no se me ocurre nada para poder hacer un numero personalizado para cada personaje en funcion del ultimo numero que haya en la base de datos por ese personaje. ¿Alguna idea?

Re: problemas con el renombrado en una base de datos

Avatar de Eloy8857
* * * * * * *

(Nivel 4 - 454 posts)

#7 Offline Eloy8857 Usuario 09 jun 10
Cada vez que vayas a insertar necesitarás saber sobre qué usuario tienes que sacar el máximo contador de imagen, así que si vas a insertar de dos usuarios distintos tendrás que hacer dos consultas para sacar el contador de cada una.

Si aún está todo un poco verde yo te recomendaría que no usaras la ruta completa del archivo, sino un campo para el nombre del usuario (o id cuando lo tengas) y otro para el contador. Luego harías que en conjunto formasen clave única UNIQUE INDEX (usuario, contador) y sería mucho más fácil sacar el último contador, y formar la ruta sería sencillo tanto por SQL como por PHP.

Pero si vas por el camino actual puedes unsar una consulta que te devolvería el contador. Sería algo fácil, tipo:

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(ruta, '.', 1), '_', -1) AS ult_contador FROM imagenes WHERE ruta LIKE 'usuario_%';

Acuérdate de escapar el guión bajo con una contrabarra en el LIKE. Aquí no te lo pongo porque el foro no los muestra :P

Saludos.

Restless Souls Online: se viene un gran MMORPG

Re: problemas con el renombrado en una base de datos

Avatar de yuber
* * * * * * *

(Nivel 1 - 30 posts)

#8 Offline yuber Usuario 14 jun 10
Bueno, de nuevo aqui, he utilizado tu solucion pero la he tenido que dividir en 2 sentencias por que se me hace mas senillo, no obstante no me acaba de funcionar, la verdad que tengo mucho codigo, pero el tema de que se quede con el ultimo contador no lo hace bien, este es mi codigo.

   
     
 $totalimagenes=count($imagenespequenas);
 //echo $totalimagenes;
   echo '<br />';
   for ($i = 0; $i < $totalimagenes; $i++){
    $imagenespequenas=$_FILES["imagenespequenas"]["name"][$i];
    //echo $imagenespequenas;
         $tmp = $_FILES["imagenespequenas"]["tmp_name"][$i];
         
   
              
         
         
         
 if($imagenespequenas!="")
{          //esto se hace para dividir las imagenes pequeñas en nombre y extension y asi poder agregar la extension al renombrado
        $partes=explode(".",$imagenespequenas);
        //variable para renombrar en funcion del personaje
        //$renomdestino=$nompersonaje.'_'.$i.'.'.$partes[1];

       
        //PARA RENOMBRAR LAS IMAGENES NUMERANDO POR PERSONAJE
    //ESTO MUESTRA LA ULTIMA IMAGEN EN FUNCION DEL PERSONAJE QUE INSERTAMOS
    $sql="SELECT nombre_imagen FROM imagenes WHERE nombre_imagen LIKE '%".$nompersonaje."%' ORDER BY codimagen DESC";
     $consulta = mysql_query($sql, $conexion);
     $registros=mysql_fetch_array($consulta);
     $ultimaimagen=$registros["nombre_imagen"];
     echo 'xxxx ultima imagen xxxx <i>'.$ultimaimagen.'</i>';
     echo '<br />';
     
    //PARA RENOMBRAR CADA IMAGEN INDEPENDIENTEMENTE
    $sql="SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('".$ultimaimagen."', '.', 1), '_', -1) AS test";
    $consulta = mysql_query($sql, $conexion);
    $registros=mysql_fetch_array($consulta);
    $totalregistros=mysql_num_rows($consulta);
    echo $sql;
    echo '<br />';
    //echo 'TOTALREGISTROS'.$totalregistros;
     echo '<br />';
     $digitos=$registros["test"];
    echo 'ultimaimagenintroducida'.$digitos;
       
    if($totalregistros=="1")
    {$contador=$digitos;}
    if($totalregistros=="0")
    {$contador="001";}
     echo '<br />';
    echo 'CONTADOR'.$contador;
   
   
   
    $renomdestino=strtolower($nompersonaje.'_'.$contador.'.'.$partes[1]);

       //RENOMBRANDO
        rename($imagenespequenas,$renomdestino);
 
   
   
        $sql="INSERT INTO imagenes (codpersonaje_imagen, nombre_imagen) VALUES ('".$codpersonaje."','".$renomdestino."') ";
   echo '<br />';
  

   //MOVIENDO LAS IMAGENES
           move_uploaded_file($tmp,"imagenes/imagenespequenas/".$renomdestino);
           
                         $consulta = mysql_query($sql, $conexion);
             
   
   
}
$contador++;
            }


Como ves, la division es algo asi
esta sentencia

SELECT nombre_imagen FROM imagenes WHERE nombre_imagen LIKE '%".$nompersonaje."%' ORDER BY codimagen DESC";

lo que hace es buscar el ultima imagen del  personaje insertado en la base de datos

y luego con la tuya

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('".$ultimaimagen."', '.', 1), '_', -1) AS test";



lo que hacemos es coger esa imagen de la sentencia de arriba y sacar simplemente el  numero.

if($totalregistros=="1")

    {$contador=$digitos;}

    if($totalregistros=="0")

    {$contador="001";}

     echo '<br />';

    echo 'CONTADOR'.$contador;

Si te fijas en el codigo de arriba verás una variable $contador, esa variable era la que queria usar para renombrar dinamicamente a las imagenes, si la consulta inicial(mysql_num_rows) da algún resultado, eso querrá decir que habrá algun personaje por lo que asignamos el valor de los digitos(calculado con las 2 sentencias de arriba) a $contador si no, ponemos el valor de%contador a 1, no estoy muy seguro de este codigo por eso pido una vez mas tu ayuda, para terminar ya de perfilarlo,por que no acaba de funcionar bien.
Si te preguntas donde renombra  usando $contador es aqui.

  $renomdestino=strtolower($nompersonaje.'_'.$contador.'.'.$partes[1]);

       //RENOMBRANDO
        rename($imagenespequenas,$renomdestino);
  

Re: problemas con el renombrado en una base de datos

Avatar de Eloy8857
* * * * * * *

(Nivel 4 - 454 posts)

#9 Offline Eloy8857 Usuario 15 jun 10
Pero es que SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('".$ultimaimagen."', '.', 1), '_', -1) AS test era un ejemplo, tienes que adaptar la última consulta que te pasé para sacar el contador más alto.

Saludos.

Restless Souls Online: se viene un gran MMORPG

Re: problemas con el renombrado en una base de datos

Avatar de yuber
* * * * * * *

(Nivel 1 - 30 posts)

#10 Offline yuber Usuario 15 jun 10
De hecho solo necesite una pequeña adaptacion que fue la de .$ultimaimagen en el select substring, es mas, las dos consultas funcionan a la perfeccíon, la primera te saca el nombre de la imagen con el contador mas alto y esta segunda te saca ese contador, el problema es que ese contador no lo puedo usar para renombrar las siguientes imagenes, no lo usa, no sé si hay que reconvertir ese contador de algún modo para poder renombrarlo ya que igual por estar en formato base de datos no lo coge bien o hay que hacerlo de otro modo, pero repito el problema me viene al renombrar las imagenes con ese contador no en las sentencias sql que funcionan bien.

Re: problemas con el renombrado en una base de datos

Avatar de Eloy8857
* * * * * * *

(Nivel 4 - 454 posts)

#11 Offline Eloy8857 Usuario 16 jun 10
Bueno eso es lo de siempre... move_uploaded_file te permite darle el nombre que quieras al archivo, no necesitas ningún rename ni nada más. Simplemente mueve el archivo dándole el nombre que quieres.

Saludos.

Restless Souls Online: se viene un gran MMORPG

Re: problemas con el renombrado en una base de datos

Avatar de yuber
* * * * * * *

(Nivel 1 - 30 posts)

#12 Offline yuber Usuario 16 jun 10
pero justamente es parte del problema que hay, que lo mueve pero no coge ese contador, es decir si la imagen renombrada tiene que ser, por ejemplo

haniballecter_587.jpg

despues de renombrarla aparece esto

hanniballecter_.jpg

no esta cogiendo bien la cadena sql, y bueno ya no hablo de cuando quieras insertar mas de una imagen a la vez, si con una ya no lo hace con 2 o mas nada de nada

Re: problemas con el renombrado en una base de datos

Avatar de Eloy8857
* * * * * * *

(Nivel 4 - 454 posts)

#13 Offline Eloy8857 Usuario 17 jun 10
Mirando el último código grande que pusiste te puedo aconsejar que el número de la última imagen lo saques en una única consulta:


$sql="SELECT nombre_imagen FROM imagenes WHERE nombre_imagen LIKE '%".$nompersonaje."%' ORDER BY codimagen DESC";
$sql="SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('".$ultimaimagen."', '.', 1), '_', -1) AS test";
//Combinadas quedaría...
$sql="SELECT nombre_imagen, SUBSTRING_INDEX(SUBSTRING_INDEX(nombre_imagen, '.', 1), '_', -1) AS ultimo_indice FROM imagenes WHERE nombre_imagen LIKE '%".$nompersonaje."%' ORDER BY codimagen DESC LIMIT 1";



El LIMIT es porque sólo necesitas un registro, ahorra ancho de banda y memoria :P

Debuguea a ver qué contienen las variables $contador y $renomdestino porque falla en algún punto. Si no lo encuentras pega a ver el código catualizado para mirarlo (ponlo entre las etiquetas [ php ] y [ /php ] sin espacios, para que lo formatee el foro).

Saludos.

Restless Souls Online: se viene un gran MMORPG

Responder mensaje

Para poder participar debes estar registrado e identificado. Si no estás registrado como usuario de PHP-Hispano, :: Registrar ::
Login / Password   

php-hispano.net 2002 - 2010 | XHTML 1.0
Datos Legales | Webmaster