Показать полную графическую версию : PHP - несколько вопросов
<?php
$tmp_name = ' *math* '; // реальный (относительный, а не абсолютный, естессно) адрес файла на сервере
$final_path = $tmp_name; // копия предыдущей переменной с более красивым именем
if (is_uploaded_file($_FILES['userfile']['tmp_name'])) { // Как поля USERFILE и TMP_NAME берут свои значения? пробовал вписывать вместо tmp_name следующее: $tmp_name и final_path, что приводило к ошибке (если можно, объясни мне синтаксис процедуры is_uploaded_files, я работаю с php5)
echo "File ". $_FILES['userfile']['name'] ." uploaded successfully.\n"; // Как берётся значение NAME? это тоже стандартная переменная... и что значит \n в конце строки??
echo "Displaying contents\n";
readfile($_FILES['userfile']['tmp_name']); // что делается в этой строке?
} else {
echo "Possible file upload attack: "; // Что имеется ввиду под атакой? Я не совсем понимаю условия процедуры is_uploaded_files. Поясните пожалуйста.
echo "filename '". $_FILES['userfile']['tmp_name'] . "'.";
}
move_uploaded_file($_FILES['userfile']['tmp_name'], "$final_path"); // после исполнения php-файла, загруженных файлов в указаном каталоге (допустим, папка "content") не обнаружена, т.е. процедура move не работает или я чего-то не понимаю...
$file = $_FILES['$userfile']['$tmp_name'];
$getTime = date("H:i:s");
$filestat = @stat($file);
$meta = id3_get_tag($file); // ID3 не установлен по умолчанию в PHP. Кажется, он устанавливается из дистрибутива PEAR? Как установить PEAR на PHP5 ? (используемый php5 встроен в Denver и используется так)
$query = "INSERT INTO MediaLib(id, folder, title, albumn, performer, date, filesize, link, metadata) VALUES (NULL, " . $file_dir . ", " . $meta['title'] . "," . $meta['album'] . "," . $meta['artist'] . ", " . $getTime . ", " . $filestat['size'] . ", " . $final_path . ", " . $meta . ")";
mysql_query ($query); // должна создаться новая строка в БД (2 строки подключения к MySQL-серверу и к БД в начале скрипта я пропустил, я про них помню), где id, folder, и т.д. названия заголовков столбцов в таблице, а $file_dir - это, например, значение в столбике folder таблицы.. я правильно понимая? тут нет никаких подводных камней?
?>
В итоге, как сделать, чтобы MOVE перемещала файл в папку, адрес которой задаётся из переменной $final_path, а не выводила на экран (сейчас файл загружается в текстовом виде в окно браузера).
Как установить поддержку ID3_Tags и PEAR вообще? :blush:
Под *math*понимается некоторая функция, которая смотрит сколько было файлов в последнем каталоге, и если он заполнен, меняет адрес каталога на новый. Как написать такую функцию?
function count_files() {
global $final_path;
$nya = 0;
if ($handle = opendir($final_path)) {
while (false !== ($file = readdir($handle))) {
$nya++;
}
if ($nya > 100) return $final_path . "_new"; // если та папка содержит больше 100 файлов, добавляем в конец имени _new
else return $final_path; // иначе не добавляем
}
// а теперь вызываем эту функцию:
$tmp_name = count_files();
if (is_uploaded_file($_FILES['userfile']['tmp_name'])) { // Как поля USERFILE и TMP_NAME берут свои значения? пробовал вписывать вместо tmp_name следующее: $tmp_name и final_path, что приводило к ошибке (если можно, объясни мне синтаксис процедуры is_uploaded_files, я работаю с php5)
userfile - это браузер посылает:
<file name="userfile" />
tmp_name - когда файл закачивается на сервер, он закачивается во временную папку под временным именем. И в этой переменной как раз содержится этот временный путь.
echo "File ". $_FILES['userfile']['name'] ." uploaded successfully.\n"; // Как берётся значение NAME? это тоже стандартная переменная... и что значит \n в конце строки??
name - это оригинальное имя файла. \n - перенос строки.
readfile($_FILES['userfile']['tmp_name']); // что делается в этой строке?
Функция readfile() выводит файл на экран. Если не надо выводить - удалите эту строку.
Насчёт id3_tags не знаю. Как-то ставится, наверное :))
echo "Possible file upload attack: "; // Что имеется ввиду под атакой? Я не совсем понимаю условия процедуры is_uploaded_files. Поясните пожалуйста.
Если файл загружен не полностью, то выполняется код из этого блока. Здесь просто выводится сообщение "Может быть вы злобный хацкер?" :)
С ID3 проблема решилась (кажется) - скачать функции IDv3 (и не только v3) можно на сайте www.getid3.org (это если кому-то не хочется мучаться с PEAR :) ).
Спасибо за разъяснения..
Теперь вопрос на засыпку:
Как интегрировать форум vBulletin в CMS? (SilverStripeCMS v0.3.1SB, если конкретно)
Я расчитываю получить минимум умный ответ на глупый вопрос :)
Мне хотябы надо знать в какой последовательности и какие действия выполнять, боюсь упустить что-нибудь важное...
Автоматически запихать как модуль CMS с минимальной отладкой с моей стороны не получится? Если всё-таки получится, то каким образом это примерно делается? (а лучше точно ^_^ )
Ошибка
SQL-запрос:
CREATE TABLE `CoreLibrary` (
`ID` INT( 5 ) UNSIGNED AUTO_INCREMENT ,
`Folder` TEXT NOT NULL ,
`Title` TEXT NOT NULL ,
`Album` TEXT NOT NULL ,
`Performer` TEXT NOT NULL ,
`Date` DATE NOT NULL ,
`FileSize` FLOAT NOT NULL ,
`Link` TEXT NOT NULL ,
`MetaData` SET NOT NULL ,
PRIMARY KEY ( `ID` )
)
Ответ MySQL: Документация
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOT NULL ,
PRIMARY KEY ( `ID` )
)' at line 10
Что за неведома ошибка возникает при создании БД в MySQL? И как от неё избавиться?
Оказалось, ошибка возникла из-за использования типа SET в поле MetaData.
Видимо, неправильно его использую... То же самое, если тип ENUM.
Как правильно создавать поля таких типов?
Русскоязычная документация по MySQL (http://www.mysql.ru/docs/man/). Там есть всё, что надо. И это всё легко ищется по оглавлению.
Вкратце:
... SET ("ня", "nya", "мур", "мяу") NOT NULL ...
... ENUM ("ня", "nya", "мур", "мяу") NOT NULL ...
Превосходно! а в чём разница между SET и ENUM? (читал на php.su, так и не понял)
Можно ли сделать так, чтобы в поле MetaData (SET или ENUM) автоматически переносились соответствующие значения из полей Title, Album, Performer?
И как адекватно искать по полю типа ENUM или SET?
Допустим, поиск по запросу "ня" в этом поле вернёт true или false?
А по запросу "мур ня"?
В set и enum можно заносить только те значения, которые явным образом заданы при создании таблицы.
Т.е. вы создали таблицу и указали, что могут принимать такие значения ("ня", "nya", "мур", "мяу"). Далее при добавлении строк, в это поле можно вносить только данные слова и никаких других. Это контроль со стороны СУБД. Скажем, вам нужно, чтобы в списке товаров были только Москва, Архангельск и Челябинск. И никаких Урюпинсков добавить нельзя будет.
Разница между set и enum в том, что enum допускает только 1 значение в строке ("ня", например), а set - несколько (начиная от нуля). Например: "ня","nya".
А зачем заносить значения из Title, Album, Performer ещё куда-то? Поиск от этого быстрее не станет, а база данных разрастётся. Вы можете искать нужное название сложным запросом. Скажем, ищем слово "coutty" среди этих полей, причём 'coutty' - это не полное слово. Может быть и 'coutty на отдыхе', и 'кот coutty':
"SELECT * FROM `my_table` WHERE `Title` LIKE '%coutty%' OR `Album` LIKE '%coutty%' OR `Performer` LIKE '%coutty%' ORDER BY `Title`, `Album`, `Performer`";
Звучит хорошо... Попробую)
А если вернуться к закачке файлов на сервер... они у меня не закачиваются в Z:\tmp\ (хотя tmp_name возвращает адрес вид Z:\tmp\XXX.tmp, но такого файла в папке я не обнаруживаю и переместить несуществующий файл функцией move_uploaded_files соответственно тоже не получается)... в чём проблема?
Файлы загружаются ^_^
Осталась проблема с распределением их по директориям... Не догоняю условие:
if ($handle = opendir($final_path)) {
while (false !== ($file = readdir($handle))) {
$nya++;
Проблема в том, что $nya++ никогда не происходит (хотя по логике должно) и $nya всегда остаётся в начальном значении (т.е. в нуле).
Вообще выражение "Пока ЛОЖЬ не РАВНО <ПЕРЕМЕННАЯ> присвоить функция (параметр) делать... " меня как-то пугает... уж больно неструктурно это выглядит :) (хотя на php.su приведён именно такой пример).
Может быть неверно задаётся адрес директории?
Выведите переменную: echo $final_path перед выполнением этого ветвления.
Вообще, здесь надо использовать относительный путь, а не абсолютный. Например: opendir("./images/dir0001")
Вообще выражение "Пока ЛОЖЬ не РАВНО <ПЕРЕМЕННАЯ> присвоить функция (параметр) делать... " меня как-то пугает... уж больно неструктурно это выглядит (хотя на php.su приведён именно такой пример). »
Это пример из официальной документации php. От перемены мест сравниваемых, результат не меняется. Но исключается возможность присваивания вместо сравнения (иногда по ошибке можно написать if ($a = false) { ... }. А вот обратное присваивание точно выдаст ошибку: if (false = $a) { ... } ).
Добавление в базу сделано.
Теперь надо написать поиск.
Поиск должен искать слова из 1 строки сразу в 3 столбцах таблицы и выдавать результаты по их релевантности.
Сколько не бился - толком ничего не вышло.
Подскажите, а? http://opera-ac.clan.su/smilies/christmas/sad.gif
И/или хотя бы обясните пословно, что здесь написано:
"SELECT id FROM CoreLibrary WHERE title LIKE '%". str_replace(" ", "%' OR title LIKE '%", $good). "%'"
($good - данные из строки поиска)
Знак % что даёт? и кавычки как-то странно стоят, аж жуть....
А вот здесь ещё непонятнее:
"SELECT *, MATCH row1 AGAINST ('$search')+MATCH row2 AGAINST ('$search')+MATCH row3 AGAINST //('$search') as relev FROM CoreLibrary ORDER BY relev DESC"
здесь $search = $good в пред. случае.
AGAINST? MATCH? DESC?
"SELECT id FROM CoreLibrary WHERE title LIKE '%". str_replace(" ", "%' OR title LIKE '%", $good). "%'"
Выбрать столбец id из таблицы CoreLibrary, где запись в столбце title совпадает с маской поиска (LIKE). Маска поиска состоит из строки запроса ($good), где функцией php str_replace() заменяются пробелы на знаки процента, которые дополнительно добавляются в начале и в конце строки. Знак процента в SQL означает "любые символы". Как * в Windows. Также к результатам добавляются строки (OR), где идёт поиск только по заданной строке, хотя я не вижу в этом смысла - всё равно ведь % их найдёт.
Но согласен, скобки стоят странно. Было бы правильнее расставить их так:
"SELECT id FROM CoreLibrary WHERE title LIKE '%". str_replace(" ", "%", $good) . "%' OR title LIKE '". $good . "'"
Второй запрос:
"SELECT *, MATCH row1 AGAINST ('$search')+MATCH row2 AGAINST ('$search')+MATCH row3 AGAINST //('$search') as relev FROM CoreLibrary ORDER BY relev DESC"
Да, здесь посложнее.
SELECT *, ... - выбрать все строки, удовлетворяющие условию, и справа добавить столбец relev - релевантность поиска (по нему потом идёт сортировка).
MATCH колонка AGAINST ('строка поиска') - полнотекстовый поиск по столбцу. Таблицы должны иметь индекс для полнотекстового поиска. Видимо, здесь идут три подзапроса по разным столбцам, потом им задаётся общее имя (AS relev) и по этой колонке (ORDER BY relev) уже сортируется по убыванию (DESC).
Хотя странно выглядит)
Подробнее о полнотекстовом поиске можете почитать здесь (http://www.opennet.ru/base/dev/mysql_pgsql_search.txt.html), если интересно. Я не совсем разобрался =~_~=
Последний запрос (с релевантностью) возвращает таблицу целиком с дополнительным столбиком "relev", в котором одни нули... Почему? $search совпадает со значениями row1 в двух строках.
И где можно получить информацию по "ERROR: "Неизвестная строка с пунктуацией @ 96"" (cобственно, интересуют описания этих самых @96, @100 и т.д.)
Вопрос про нолики отпал... И правда, релевантность начинает подсчитываться, когда в базе 10 и более записей...
Теперь, как с ней манипулировать? Чтобы при точных запросах по нескольким столбцам таблицы выдавала только точные ответы (как в медиапоисковиках или поиске по электронным библиотекам,например)
При точных запросах вам не нужна релевантность. Вам нужно точное совпадение:
SELECT * FROM table_name WHERE stolb1 = 'запрос' OR stolb2 = 'запрос' OR stolb3 = 'запрос'
Но обычно полную строку никто не ищет, поэтому вместо stolb = 'запрос' пишите stolb LIKE '%запрос%'. Т.е. пробелы внутри запроса будут обрабатываться как есть, но сама подстрока будет обнаруживаться как в начале, так в середине и конце строк.
Чтобы упорядочить выдачу, добавьте в конце ORDER BY stolb_name ASC
ASC - по возрастанию (указывать не обязательно, т.к. по умолчанию), DESC - по убыванию. Можно указать несколько полей через запятую, тогда упорядочивание будет производиться сначала по первому, потом по второму и т.д.(имеется в виду, что в первом поле "автор" Пушкин будет идти после Гоголя, конечно, но у самого Пушкина произведения будут упорядочены по второму полю "название").
Прим: LIKE - странная штука. Когда я делал поиск по прайсу, она находила даже запросы длиной меньше 4 символов, но что это были за результаты... Каждый раз что-то своё. И только больше 4 символов запроса находились точно.
С этим разобрались. Я решил пока что отказаться от LIKE и всё выполнил через MATCH AGAINST.
В SQL мой запрос работает отлично, а вот в написанном PHP'шнике - шиш.
Суть php-файла:
// забираем данные из формы в переменную $search и обрабатываем её
$good = trim(preg_replace("/\s(\S{1,1})\s/", " ", ereg_replace(" +", " "," $search ")));
// вывод $good на экран показал, что выводится она правильно (в соответствии с запросом в $search)
// ...
$sql = "SELECT *, MATCH title AGAINST ('$good')+MATCH avtor AGAINST ('$good')+MATCH genre AGAINST ('$good') AS Relev FROM $table WHERE MATCH (avtor) AGAINST ('$good') ORDER BY Relev DESC"; // в SQL это работало!!
$result = mysql_query($sql) or die ("err_code = " . mysql_error()); //ошибки не выдаёт
echo $result; // возвращает Resource id 3, пробовал count($result) как для массива, вернуло значение 1 (1 элемент в переменной $result)
В чём теперь дело?
Может я обращение к результатам запроса неправильно делаю? или что ещё?
Вы бы почитали руководство PHP касательно работы с MySQL. Там даже примеры есть.
mysql_query() и должно возвращать идентификатор ресурса. Теперь его надо обработать:
echo "<table>";
while ($line = mysql_fetch_assoc($result)) // возвращает одну строку из ресурса в виде ассоциативного массива
{
echo "<tr><td>$line['stolb1']</td><td>$line['stolb2']</td><td>$line['stolb3']</td></tr>";
}
Тьфу ты, точно... Вылетело из головы >_<
Спасибо!
echo "<table>";
while ($line = mysql_fetch_assoc($result)) // возвращает одну строку из ресурса в виде ассоциативного массива
{
echo "<tr><td>$line['stolb1']</td><td>$line['stolb2']</td><td>$line['stolb3']</td></tr>";
} »
Вот только так не прокатит на самом деле. Ассоциированные массивы не имеют индексов.
Поэтому придётся использовать конструкцию типа foreach ($array as $value) { *** последовательная обработка элементов строки*** }
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.