Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

HTML+CSS+JavaScript

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Подгрузка файлов без перезагрузки страницы
 
 автор: algoritm2   (03.12.2016 в 04:28)   письмо автору
 
 

Если например у пользователя открыта в одном окне страница с его файлами которые он добавил ранее, то в другом окне он может открыть страницу с формой где можно добавить еще файл. При добавлении нового файла первая страница автоматически обновляется. Это обновление я сделал с помощью функции setTimeout. Но эта функция срабатывает постоянно. Т.е. постоянно ссылается в базу данных и вынимает от туда все данные. Можно ли сделать, чтобы данные вынимались только тогда когда пользователь добавил файл, т.е. обновление происходило при добавлении очередного файла.

Весь код ниже.
index.php

<?php
include "config.php";//Подключаем БД
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; Charset=UTF-8">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<a href="/file_add.php" target="_blank">Добавить файл</a>
<div id="content"></div>

<script>
$(document).ready(function()
{

var AjaxViborkaTimeout = 1500;
function AjaxViborka()
{
  $.ajax
  ({
      type: "POST",
      url: "show.php",
      data: {UseFunction : 'IsChall'},
      success: function(html){
      $("#content").html(html);
  }
  }).done(function(otvet_php) 
   {
      setTimeout(AjaxViborka,AjaxViborkaTimeout);
   });
}
AjaxViborka();  
});
</script>

</body>
</html>

show.php
<?php
if (empty($_POST['UseFunction'])) exit(0);

$function 'Run' $_POST['UseFunction'];

if (!
function_exists($function)) exit(0);
$function();

function 
RunIsChall()
{
  include 
"config.php"//Подключаем БД
   
$query "select * from attachment WHERE user_id=1";
   
$result mysql_query($query) or die(mysql_error());
   while (
$row=mysql_fetch_array($result))
    {
       print 
"<a href=$row[name]>$row[name]</a><br>";
    }
   
   exit(
0);
}

?>

config.php

<?php
$hostname 
"localhost"
$username "root";
$password "";
$dbName "test5";


mysql_connect($hostname$username$password) or die ("Не могу создать соединение");
mysql_query('SET NAMES utf8') or header('Location: Error');
header("Content-Type: text/html; charset=utf-8");
mysql_select_db($dbName) or die (mysql_error());
?>


file_add.php

<?php
  
include "config.php";//Подключаем БД
?>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; Charset=UTF-8">
  <title>Результат загрузки файла</title>
</head>
<body>
<h2><p><b> Форма для загрузки файлов </b></p></h2>
      <form action="upload.php" method="post" enctype="multipart/form-data">
      <input type="file" name="filename"><br> 
      <input type="submit" value="Загрузить"><br>
</form>
</body>
</html>


upload.php

<?php
  
include "config.php";
?>
<html>
<head>
  <title>Результат загрузки файла</title>
</head>
<body>
<?php
   
if($_FILES["filename"]["size"] > 1024*3*1024)
   {
     echo (
"Размер файла превышает три мегабайта");
     exit;
   }
 
   if(
is_uploaded_file($_FILES["filename"]["tmp_name"]))
   {
      
$filename $_FILES["filename"]["name"];
      
move_uploaded_file($_FILES["filename"]["tmp_name"], $_FILES["filename"]["name"]);
      
mysql_query("INSERT into attachment (name, user_id) VALUES('$filename', 1)");
   } else 
   {
      echo(
"Ошибка загрузки файла");
   }
?>
</body>
</html>

  Ответить  
 
 автор: confirm   (03.12.2016 в 19:26)   письмо автору
 
   для: algoritm2   (03.12.2016 в 04:28)
 

Версия JQ 1.7.1 слишком древняя, чтобы ее использовать. Для загрузки файла посредством Ajax совсем не требуется каких либо новых окошек, да и код показанный к загрузке файлов асинхронным способом отношения не имеет.
Просто ваш код, это костыли.

Если требуется поддержка IE8, то последняя версия JQ его поддерживающая, это версия 1.8.3. Но для того чтобы использовать асинхронную загрузку без всяких костылей, нужна поддержка HTML5, которой нет в IE8. Для него уже потребуется костыль в виде IFRAME. Подобные загрузчики уже есть как плагины к JQ, можно установить и использовать.

Упрощенно это выглядит так (все в одном файле, можно запустить и проверить на локальном сервере).

<?
if($_POST) {
    exit(
print_r($_POST1) . print_r($_FILES1));
}
?>
<!DOCTYPE HTML> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<style>

</style> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script> 
$(function() {
    $('form').on('submit', function(e){
        e.preventDefault();
        $.ajax({
            url: this.action,
            type: 'POST',
            contentType: false,
            processData: false
            data: new FormData(this),
            dataType: 'text',
            success: function(data){
                if(!!data){
                    alert(data);
                }
            }
        });
    });
});
</script>     
</head> 

<body>
    <form action="upload.php" method="post" enctype="multipart/form-data">
      <input type="text" name="file_name">
      <input type="file" name="file_body"<br>
      <input type="submit" value="Отправить">
    </form>
</body> 
</html>


Если тип возвращаемых сервером данных (результата принятия формы и загрузки файлов) dataType: 'text' заменить на json, и сервер их отдает как JSON, то легко организовать диалог клиент-сервер: обработка ошибок, успешное выполнение, включая и передачу ссылки (имя) загруженного файла, который можно отобразить у клиента.

Вот только загрузку файлов сервером начинают не с if($_FILES["filename"]["size"] > ..., а с проверки $_FILES["filename"]["error"] и если ошибок нет, тогда перемещаем файл.

$filename = $_FILES["filename"]["name"]; - это во-первых опасно, и как минимум для файла $filename = basename($_FILES["filename"]["name"]); и sql-инъекция еще не умерла, а данное поле можно и подменить. К тому же, нет гарантии того, что каждый пользователь (и даже один и тот же) дает уникальные имена своим файлам, и если они складываются в кучу, то будет перезапись файла. Именовать файлы для хранения должен сервер, а оригинальное имя файла можно сохранить в базе.

  Ответить  
 
 автор: algoritm2   (05.12.2016 в 02:24)   письмо автору
 
   для: confirm   (03.12.2016 в 19:26)
 

Где то я читал, что нельзя давать пользователю возможность придумывать самому названия файлам. Поэтому это всего лишь пример взятый отсюда. http://www.softtime.ru/scripts/upload.php
В моем случае мой код будет выглядеть вот так.



$ext = strtolower(strrchr($_FILES["filename"]["name"],"."));
.....
if(!empty($_FILES['filename']['tmp_name']) && $_FILES['filename']['error']== UPLOAD_ERR_OK)
{
if(is_uploaded_file($_FILES['filename']['tmp_name']))
              {
                $date = time();
                $namefile = $date.$ext;
               //$p путь куда загружать файл
                $filename = $p."/".$namefile;
               
               
                move_uploaded_file($source, $filename);
              //$ext полученное расширения файла
                $img = $date.$ext;
                return $img;
              }
}
.....
]

Вот, что меня интересует открыл книгу "практика создания web-сайтов 2-е издание". Там в главе про безопасность говорится, что файл нужно проверять на пустоту.
if(!empty($_FILES['filename']['tmp_name'])) - нужно делать такую проверку если пользователи будут добавлять файлы?

Далее ваш пример только отправляет данные на сервер. А мне нужно как в чате. Только в отличии от чата у меня два окна. В первом я добавляю файл. Во втором должно быть моментальная подгрузка файла что-то вроде header(Refresh:2) в php. Следующее почему вы назвали мой код костыль. В нем есть какие-то ошибки или лазейки которые пользователь может обойти? Может быть я еще какие то уязвимости не описал, так подскажите, мне бы какой-нибудь пример, потому, что я делаю это в первый раз для пользователей, до этого все файлы добавлял сам в админке?

Я нашел одну стать http://www.php.su/articles/?cat=protocols&page=001. про загрузку файлов на сервер, там есть как загрузить картинки на сервер как это статья нормальная я имею ввиду с точки зрения безопасности?

И еще один вопрос раз моему файлу присваивается имя функция time(), то я думаю не стоит защищать файл от sql инъекции
$file = mysql_real_escape_string ($file);

$$file = strip_tags($file);

  Ответить  
 
 автор: confirm   (05.12.2016 в 13:18)   письмо автору
 
   для: algoritm2   (05.12.2016 в 02:24)
 

if(!empty($_FILES['filename']['tmp_name'])) - данным никак нельзя проверить файл на "пустоту", пустой файл это значит файл имеет размер в байтах равный 0. А под ключом 'tmp_name' массив $_FILES содержит временное имя временного файла загруженного во временную директорию, откуда вы обязаны его переместить, иначе он будет удален сборщиком мусора. То есть данное условие проверяет есть ли временное имя у загруженного файла, что в общем то лишено смысла.

>ваш пример только отправляет данные на сервер.... В первом я добавляю файл. Во втором должно быть моментальная подгрузка файла

Глупостей только не надо говорить. Пример отправляет файл на сервер и дает ответ клиенту по результату загрузки, и это все, что нужно от сервера. А вы чего хотели, чтобы он вам и файл вернул?

В примере асинхронный запрос, клеить какие-то окна ради загрузки файла зачем? В примере моем показан принцип, а конкретный код должен содержать конкретный диалог зависящий не только от того чего вам надо, но и от структуры клиентской страницы, и от серверного обработчика.

Если на странице А отображаются файлы, которые ранее были загружены, а асинхронный запрос с этой же страницы (плодить новую совсем не нужно) отправляет на сервер новый файл, выбранный клиентом на этой же странице, то - если есть ошибки загрузки, то сервер возвращает их. Если же загрузка прошла успешно, сервер возвращает сформированное им имя загруженного файла (возможно еще и путь), а клиентский скрипт добавляет в список ранее загруженных файлов новое изображение, src которого и вернул сервер - загруженный файл будет отображен на странице А. Зачем Refresh?

Если сервер формирует свое имя, то да mysql_real_escape_string, но в вашем коде в базу пишется то, что прислал клиент, поэтому и было сделано замечание.

  Ответить  
 
 автор: algoritm2   (06.12.2016 в 00:46)   письмо автору
 
   для: confirm   (05.12.2016 в 13:18)
 

Знаете есть движок по созданию форума называется vBulletin. Там есть такая фишка, что можно приаттачить файл. Для этого нужно нажать кнопку Manage Attachments. И откроется новое окно где можно загрузить файл. При загрузки файла в первом окне где нужно писать пост автоматически отобразиться файл. Для этого нужен, что-то вроде Refresh как на PHP, чтобы обновлять окно. Я это сделал с помощью setInterval. Прочитал вот эту статью по Ajax и php создание чата http://medv.io/create-php-ajax-chat/ и вот эту статью http://www.php.su/articles/?cat=protocols&page=001, чтобы установить ограничения на загружаемый файл.

И получилось вот что.

Файл index.php

<?php 
include "config.php";//Подключаем БД
?>
<!DOCTYPE HTML> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; Charset=UTF-8"> 
<script type="text/javascript" src="js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="/utils/tags/bbcode/js/bb.js"></script> 
 <script type="text/javascript">
     $(document).ready(function () 
     {
          setInterval("Load();", 1500);
     });
     var last_message_id = 0;
     var load_in_process = false;
     function Load() 
     {
        if(!load_in_process)
        {
          load_in_process = true; // загрузка началась 
          $.post("show.php",
          {
            act : "load", // указываем на то что это загрузка сообщений
            last: last_message_id, // передаём номер последнего сообщения который получил пользователь в прошлую загрузку
          },
          function (result) 
          {  
                load_in_process = false;
          });
        }
     }
 
 </script>
</head> 
<body> 
 

<a href="/file_add.php" target="_blank">Добавить файл</a>

<form action="" method="post">

<table border="1">
                    <tr>
                      <td>
                      <p>          
                    <label>Краткое описание
                    <br>
                    <textarea id="description" name="description" cols="40" rows="15">
<?PHP echo htmlspecialchars($_POST['description'], ENT_QUOTES); ?></textarea>
                        </label>
                                 </p>
                        <br>
                          <?php include '/utils/tags/post_des.php'?>    
                        <br>
                        </td>
                    </tr>
                    
</table>

</form>
 <div> 
     <div id="content"></div>
 </div> 
</body> 
</html> 

Файл show.php

<?php
 
include "config.php"//Подключаем БД 
 
Header("Cache-Control: no-cache, must-revalidate");
Header("Pragma: no-cache");

Header("Content-Type: text/javascript; charset=utf-8");
 
if (
$_POST['act']=="load")
{
     
Load();
}


function 
Load() 

    
$sql "SELECT path FROM filepath WHERE id = 1";
    
$res mysql_query($sql) or die(mysql_error());
    
$rowpath mysql_fetch_array($res);
    
   
$last_message_id intval($_POST['last']); 
   
    
   
$query "select * from attachment WHERE (id > $last_message_id) AND user_id=1 ORDER BY id DESC LIMIT 10"
   
$result mysql_query($query) or die(mysql_error());
   if (
mysql_num_rows($result) > 0
    {
        
$js 'var chat = $("#content");'
        
$messages = array();
        while (
$row=mysql_fetch_array($result)) 
        { 
             
$messages[] = $row;
        }
        
$last_message_id $messages[0]['id']; 
        
$messages array_reverse($messages);
        foreach (
$messages as $value
        {
            
$js .= 'chat.append("<a href='.$rowpath[path]."/".$value['name'].
' target=\'_blank\'>' $value['name'] . '</a> 
<a href=\'#\' onclick=\"click_bb(\'description\',\'img\', \'img\','
."\'".$rowpath['path']."/".$value['name']."\'".');\">
Добавит файл</a><br>");'
;
         
         }
         
$js .= "last_message_id = $last_message_id;";
         echo 
$js;
    }


?>

Файл file_add.php

<?php
   
include "config.php";//Подключаем БД
   
$sql "SELECT path FROM filepath WHERE id=1";
   
$res mysql_query($sql);
   
$row mysql_fetch_array($res);
  
  function 
upload_files($p)
  {
        
$max_image_width    640;
        
$max_image_height    480;
        
$type $_FILES['filename']['type'];
       
        
$filename $_FILES['filename']['name'];
        
$source $_FILES['filename']['tmp_name'];
        
$max_image_size        64 1024;
       
        
$ext strtolower(strrchr($_FILES["filename"]["name"],"."));
        
$blacklist = array(".jpg",".png",".jpeg");
        
        
//Проверка на ошибки
        
if($_FILES['filename']['error']==UPLOAD_ERR_OK)
        {
          if(
in_array($ext,$blacklist))
          {
            
//Максимальный размер файла в КБ
            
if(filesize($source) < $max_image_size)
            {
                if(
is_uploaded_file($_FILES['filename']['tmp_name']))
                {
                  
//Проверка ширины и высоты картинки
                  
$size GetImageSize($source);
                  
//var_dump($size);
                  
if (($size) && ($size[0] <= $max_image_width) && ($size[1] <= $max_image_height))
                  {
                      
$date time();
                      
$namefile $date.$ext;
                      
$filename $p."/".$namefile;
                     
                      
move_uploaded_file($source$filename);
                      
                      
$img $date.$ext;
                      return 
$img;
                  }
                  else return exit(
"Не верные ширина и высота изображения. 
Должно быть ширина: "
$max_image_width." px Высота: $max_image_height");
                  
                }
                else return exit(
"Выберите файл");
            
            
                
            }
            else return exit(
"Слишком большой размер");
          }
          else return exit(
"Не верный формат");
       }
       else return exit(
"Ошибки");
  }


  
$query mysql_query("SELECT COUNT(*) FROM attachment WHERE user_id = 1");
 
  
$result mysql_result($query,0);

  
$maxcount 5;

 if(!empty(
$_POST))
  {
    
//Проверка файла на пустоту
    
if($_FILES['filename']["name"]!="")
    {
      if(
$result $maxcount)
      {
         
$img upload_files($row["path"]);
         
mysql_query("INSERT into attachment (name, user_id) VALUES('$img', 1)");
         
header("Location: /file_add.php");
      }
      echo 
"Вы не можете загрузить больше $maxcount файлов<br>";
    }
    else
    {
      echo 
"Выберите файл<br>";
    }
    
     
  }
  echo 
"Количестов файлов: ".$result;
  
?>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; Charset=UTF-8">
  <title>Загрузка файлов</title>
</head>
<body>
<h2><p><b> Форма для загрузки файлов </b></p></h2>
<form name="bbform" action="" method="post" enctype="multipart/form-data">
      <input name="filename" type="file" id="filename" size="30"><br>
      <input name="submit" type="submit" value="Загрузить"><br>
</form>
</body>
</html>

  Ответить  
 
 автор: confirm   (06.12.2016 в 11:58)   письмо автору
 
   для: algoritm2   (06.12.2016 в 00:46)
 

Ересь полная. Вы не понимаете что есть такое Ajax, и что это асинхронный процесс. И запомните - новое окно и именно окно, это приложение, хотя оно и будет дочерним для основного окна. А еще называют окнами всякие плюшки всплывающие на страницах, которые к окну никакого отношения не имеют, ибо являются DOM элементами текущего документа, порожденные посредством JS.

Чего вам надо? Меньше заглядывайте в движки, и больше читайте доки, изучайте суть работы того или иного. Не нужно никакого таймера для данной задачи, нужно только понять что такое есть асинхронность, которая в JS сплошь и рядом. И как это все должно работать я уже писал, и код для этого очень простой, вы же наворотили такого, что... А проку от него никакого.

  Ответить  
 
 автор: algoritm2   (07.12.2016 в 00:31)   письмо автору
 
   для: confirm   (06.12.2016 в 11:58)
 

Может и никакого проку, но главное работает. Кроме ругани, что все не правильно и все плохо я не получил никакого ответа. Куда мне заглядывать и что мне читать я сам решу. Если кто-то знает альтернативу как сделать пускай покажет на каком нибудь примере. Вы мне показали какую-то кнопку которая отправляет данные на сервер. Единственно кто мне помог это тот кто написал статью как создать чат. Чего мне надо? Я написал минимум два раза.

  Ответить  
 
 автор: confirm   (07.12.2016 в 12:28)   письмо автору
 
   для: algoritm2   (07.12.2016 в 00:31)
 

Читать вы можете, а вот вникать в написанное надо учиться. Никто вас не ругает, не надо прибедняться, вам только говорят что вы пишите полную хрень, а надо бы вникнуть. Я не могу вам все от и до растолковать, нет на это времени, нужно же самому изучать то, что говорят, там более суть асинхронного обмена с сервером очень проста. И данному обмену не нужны ни "рефреш", ни таймер, последнее так это вообще кошмар. Асинхронный обмен подразумевает либо callback функцию, либо promise, а таймер это ужас в данном случае, который вполне не обеспечит нормальной работы, почему, я не скажу, потому как более чем уверен, если вы чуточку подумаете, то догадаетесь сами.
Вот на что вам указывается, но коли вы лепите горбатого по принципу "работает и хрен с ним", ну так зачем вы вообще подымаете темы на форуме?

Вам сразу был показан код, который как раз и нужен, тем более для чата. И сложного в нем ничего нет, только вместо возврата сервером массивов принятых данных, что показано как просто пример работы и что сервер принимает файлы, а конкретное нужное вам, чего кроме вас никто не знает. Пусть, к примеру, сообщения чата выводятся в DIV c id равным message, а сервер при успешной загрузке возвращает имя сформированного файла, тогда на jQuery в примере callback функции, что определена в success, добавляем изображение в окно чата:

success: function(data){ 
                if(!!data){ 
                    $('#message').append('<img src="path/'+data+'">');
                } 
            }


где data - ответ сервера содержащий имя загруженного файла, и изображение будет отображено на странице. Какие к чертовой матери таймеры и рефреши тут нужны, не понятно, как и плодить окна (если речь именно о них, что нужно тоже четко понимать).

Читайте и изучайте, задавайте конкретные вопросы по изученному, и тогда напишите что-то действительно стоящее. Ну а коли не хотите, либо будет становиться в позу обиженного, тогда увы, никто вам не поможет. Пишите тот ужас что показываете, но такой код даже и комментировать нет желания, а тем более "улучшать".

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования