IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Веб-программирование (https://www.imho.ws/forumdisplay.php?f=29)
-   -   PHP & MySQL вопросы (https://www.imho.ws/showthread.php?t=35049)

d0rM03D 23.07.2003 22:43

PHP & MySQL вопросы
 
вопросов наверно будет много:), поэтому так назвал тему.
пока окончательно созрел только один.
есть база. надо вывести определенное количество строк (например 10) начиная с определенной (номер ее записан в переменной) вверх по таблице. Если че-нить непонятно, попробую объяснить:).

d0rM03D 23.07.2003 23:16

добавление:
лучше это делать через цикл - в переменную поочереди чтобы записывались строки как массив и можно было бы в этом же цикле выводить определенные поля строки. Т.е вся проблема в функции доступа к базе.

Stasik 23.07.2003 23:21

SELECT * from table WHERE id<$i-1 AND id>$i+1

Aeon 23.07.2003 23:49

или
SELECT * from table LIMIT $id-1, 3;
(выбрать 3 ряда начиная с предстоящего номеру $id)

кстати, по моему Стас перепутал порядок - то что он написал выберет все ряды кроме $id и двух рядом с ним.

d0rM03D 24.07.2003 12:00

Вчера, пока не прочитал ваши предложения придумал свое решение с помощью функции:
Цитата:

mysql_Result($result,$i,field)
Msql_Result отображает поле из возвращенной записи. Параметры - идентификатор результата, возвращенный функцией msql(), целое число, которое является индексом записи, которую нужно просмотреть и имя поля.
Однако оно доволно запутанно, поэтому хочу спосить, какой из данных отрывков кода будет функционировать быстрее
Это с помощью вашего запроса:
PHP код:

$request "SELECT ntext, ntitle, date_format(ndate,'%e.%m.%y') as ndate1 FROM news"/*Вынемаемвсю таблицу*/
$result mysql_query($request);
$strnum=((mysql_numrows($result))-(10*$archivepage+3)); /*Такая уж у меня замысловатая формула формирования строки от которой происходит начало отсчета*/
$request "SELECT ntext, ntitle, date_format(ndate,'%e.%m.%y') FROM news LIMIT $strnum, 10"
$result mysql_query($request);
if (!
mysql_error()) {
/*Цикл вынимающий строку, как массив с числовым индексом*/
while ($row mysql_fetch_row($result)) {
    print (
"$row[1].$row[2].$row[0]);
    }
}
else {
print ("
Ошибка БД с запросе".$request. "MySQL пишет ". mysql_error());} 

Это мой вариант:
PHP код:

$request "SELECT ntext, ntitle, date_format(ndate,\'%e.%m.%y\') as ndate1 FROM news ORDER BY ndate DESC"/*Также приодиться вынимать всю таблицу*/
$result mysql_query($request);
if (!
mysql_error()) {
for (
$i=0;$i<=9;$i++) {/*Цикл вынимающий 10 строк начиная со $strnum*/
$strnum=((mysql_numrows($result))-$i-(10*($archivepage-1)+3));
print (
mysql_Result($result,$strnum,1).mysql_Result($result,$strnum,2).mysql_Result($result,$strnum,0));
if (
$strnum==0) {break;} /*При достижение начала таблице цикл прервется*/
}
else {
print (
"Ошибка БД с запросе".$request"MySQL пишет "mysql_error());}


Во втором варианте еще хорошо, что когда цикл достигнет начала базы то перестанет выводить строки на экран.
В первом же варианте плохо, что вывод идет вниз по таблице начиная с определенной строчки и если вывод начать с несуществующей строки, то ничего не выйдет. Так будет при выводе последних записей.
Я уже сам запутался:).

Кстати, как проверить за сколько сгенерировалась страница? Я тогда сам и посмотрю что быстрее...

Aeon 24.07.2003 12:11

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

во первых. правильно узнать количество записей с минимальной затратой времени и ресурсов можно так:
PHP код:

$request "SELECT count(id) FROM news";
$result mysql_query($request);
$total mysql_result($result0); 

топаем дальше. насколько я понял тебе нужна система навигации между страничками, показывая десять записей на страничку. проще всего это делается примерно так:
PHP код:

$archivepage = (!empty($archivepage)) ? $archivepage 0// номер странички
$offset $archivepage 10// умножаем номер странички на количество записей на страничке чтобы получить начальную строку.
$sql "SELECT ntext, ntitle, date_format(ndate,'%e.%m.%y') as ndate1 FROM news LIMIT $offset,10"// опять даём количество записей на страничке
$result mysql_query($sql) or die(mysql_error()); // посылаем запрос, убиваем скрипт в случае ошибки, показывая ошибку.
while($row mysql_fetch_row($result))
{
    print (
$row[1].$row[2].$row[0]);
}
// теперь заботимся о навигации
// используем переменную total успешно добытую так как я показал раньше.
if($archivepage 0)
{
    echo 
'<a href="archive.php?archivepage='.($archivepage-1).'" title="Previous 10 records">Previous 10</a>';
}
if(((
$archivepage+1)*10) <= $total)
{
    echo 
'<a href="archive.php?archivepage='.($archivepage+1).'" title="Next 10 records">Next 10</a>';


по крайней мере мне показалось что ты именно это пытаешься сделать из твоего кода... или нет?

Stasik 24.07.2003 19:12

Ой, да.. сорри

medved2002 24.07.2003 19:56

Кстати LIMIT дает не всегда желаемый результат.

d0rM03D 24.07.2003 20:07

Aeon
Спасибо.Да именно это я и хотел сделать.
Меня тоже смущало постоянно вынимать базу, еще раз спасибо что подсказал как сделать:).
Кстати, допустим у меня есть 18 записей, когда я перейду на вторую страницу архива $offset==20, как поведет себя скрипт - он же будет запршивать строки начиная с 20? Нормально себя ведет...:)

d0rM03D 24.07.2003 20:09

medved2002
будь чуть-чуть многословнее пожалуйста;)
что это за случаи?

medved2002 24.07.2003 20:36

http://www.mysql.com/doc/ru/LIMIT_optimisation.html

Aeon 24.07.2003 23:59

d0rM03D
нет, смотри на то как я сделал навигацию - если ты показываешь 20 записей на страницу и у тебя всего 18 записей, у тебя просто не будет показан линк на следующую страницу.

d0rM03D 25.07.2003 05:46

Aeon
Я малость переделал этот кусок кода, мне надо чтобы показывались ссылки на все страницы архива. В последствие хочу сделать сортировку и ссылки на строки( да что тут говорить, это будет скрипт новостей), на новости по месяцам года.
Вот как я сделал.
PHP код:

$pnumbs=(mysql_result($result0))/10+1//Подсчитываем число архива
settype($pnumbs,integer);                //Отбрасываем дробную часть 

Кстати, есть какая-нибудь функция для отбрасывания дробной части, я потому что тут извратился:).
А вот и вывод самих ссылок:
PHP код:

print Архив новостей";
$counter=1;
    while ($counter<=$pnumbs)            //Формирование ссылок на страницы архива
    {
        print "
<a href=/newsarchive.php?archivepage=".$counter.">".$counter."</a> | ";
        $counter++;
    } 


Aeon 25.07.2003 07:04

есть, конечно. floor() для округления вниз, ceil() для округления вверх. делаем так
PHP код:

$ct ceil($total/10); // округляем вверх
for($i 1$i <= $ct$i++)
{
    echo 
'<a href=/newsarchive.php?archivepage='.$i.'>'.($i).'</a>';
    if((
$i) < $ct// если это не последняя запись, показываем разделитель.
    
{
        echo 
' | ';
    }



d0rM03D 03.08.2003 17:45

Почти дописал систему администрирования новостей. ВОзник следующий вопрос.
Как лучше с точки зрения безопасности и быстродействия организовать эту систему:
1. Все скрипты (удаление, изменение etc.) засунуть в главный файл администрирования. В этом файле сделать ссылки на самого себя и в зависимости например от $QUERY_STRING или других переменных переданных GET'om уже производить действия.
2. Отличается от предыдущего что код скриптов удаления, изменения новостей etc. находиться в отдельных файлах. И в зависимости все от того же вставляеться includ'om.
3. Ссылки из основного файла будут вести не на самого себя, а на те скрипты передавая различные параметры все тем же Get'om.

Или стоит сделать как-то иначе?
И параллельно овзникает вопрос о том как лучше ограничить доступ к этим скриптам? .htaccess, сессии, coockies, 401?

Aeon 03.08.2003 18:00

d0rM03D
imho, зависит от личного предпочтения больше чем от чего-либо другого. Для безопасности один вариант ничем не предпочтительнее другого - могу посоветовать лишь все переменные настроек (как то, паролями для базы, итд.) положить в отдельный файл вне www-директории и использовать include() с абсолютной тропой для того чтобы его включать - таким образом даже при какой-нибудь грубой ошибке никто не сможет получить прямой доступ к файлу с паролями и чувствительной инфой. Все запросы от пользователей хорошо бы проверять на соответствие ожиданиям - не очень хорошо давать им возможность как-то ввести произвольный исполнимый код в систему... но это уже зависит от обстоятельств. А так, флаг в руки. Тут где-то пробегала ссылочка от Programmer`a на книжку "Secure PHP Development", советую скачать и прочитать, там много чего интересного и полезного...

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

А для прямого ограничения доступа в Апаче ничего проще и удобнее .htaccess/.htpasswd ещё не придумано. Сессии и кукисы, это хорошо если ты пишешь свою собственную систему опознания и регистрации пользователей, но если нужно лишь ограничить доступ на страничку администрации, обычно .htaccess/.htpasswd хватает с головой.

RaZEr 03.08.2003 21:03

Цитата:

ничего проще и удобнее .htaccess/.htpasswd ещё не придумано
проще ? удобнее ? не согласен. надежнее - да.

Aeon 04.08.2003 00:11

RaZEr
а что по твоему проще или удобнее? .htaccess/.htpasswd я могу настроить чтобы закрыть любую директорию на сервере меньше чем за пять минут... покажи мне какую-то систему которую я могу поставить так-же быстро... Я не говорю что это самый лёгкий метод для новичка, но если знаешь как это делается, он действительно самый быстрый и наименее трудоёмкий.

RaZEr 04.08.2003 00:21

Я говорю применительно к сайтам ... нередко нужно ограничить доступ к script.php?action=modify, но разрешить к script.php?action=show ... так вот тут твой htpasswd отдыхает ...

Aeon 04.08.2003 00:28

RaZEr
пфф... я почти всегда разбиваю административную и клиентскую секции на независимые скрипты... потому что если что-то криво написано в твоей системе (тьфу-тьфу-тьфу, не к ночи будь сказано), человек сразу получает возможность всё редактировать... а так, если оно в отдельном скрипте в отдельной директории под .htpasswd, всё таки безопасность выше... о чём собственно и спрашивал наш уважаемый d0rM03D.... (а мы с тобой тут в оффтоп ударились :grin: )

RaZEr 04.08.2003 00:38

Цитата:

я почти всегда разбиваю административную и клиентскую секции на независимые скрипты...
А я не разбиваю ... :)

d0rM03D 04.08.2003 16:35

Цитата:

а мы с тобой тут в оффтоп ударились
ой, да ладно - всегда приятно послушать знающих людей:).
Я все-таки решил разделять...
Если вы не против, то еще вопрос. Для изменения новости я вывожу форму и в ней хочу показать значения заголовка и текста новости оригинала:
PHP код:

$request "SELECT ntext, ntitle, date_format(ndate,'%e.%m.%y') as ndate FROM news WHERE id=$id";
$result mysql_query($request) or die(mysql_error());
$row mysql_fetch_row($result);
echo 
"
<table border=0 align=center>
<form action=changenews.php?archivepage="
.$archivepage."&msg=changed method=post>
<tr><td align=center><b>"
.$row[2]."<br><br>Введите новый текст новости:</b></td></tr>
<tr><td><input name=ntitle type=text maxlenght=50 size=20 value="
.$row[1]."></tr>
<tr><td><textarea name=ntext cols=50 rows=10 value=>"
.$row[0]."</textarea></tr>
<tr><td align=center><br><input type=submit value=Изменить></td></tr>\
<tr><td align=center><br><input name=id type=hidden maxlenght=4 value="
.$id."></td></tr>
</form>
</table>"


Дак вот текст новости в textarea выводиться полностью, а в текстовое поле для заголовка выводится только первое слово. Например в базе заголовок сохранен как "Введите заголовок", появиться только "Введите".

Второй вопрос если вы не против:). Есть index.php в него includ'om включены два скрипта, в каждый из которых включен один и тот же скрипт конфигурации, в котором параметры для соединения с базой и одна функция для подсчета строк в базе(функция используется в обоих скриптах). Запускаю index.php - первый скрипт вызывается нормально, а на месте второго возникает ошибка:
Цитата:

Fatal error: Cannot redeclare tablecount() (previously declared in d:\www\config.php:15) in d:\www\config.php on line 15
вроди бы нет запрета на использование одной функции в одном приложение...

RaZEr 04.08.2003 16:45

Нельзя декларировать одну ф-ию два раза ...

d0rM03D 04.08.2003 17:48

RaZEr
т.е нельзя вставлять два раза файл в котором эта функция объявлена?

Добавлено через 25 минут:
Да, похоже нельзя. Ну и фиг с ним, меня спасла ф-ция include_once :)

Кто-нибудь что-нибудь знает насчет первого вопроса?

RaZEr 04.08.2003 18:01

В том коде который ты запостил такого быть не может ... посмотри что ты в базу записал ... скорей всего это не "Введите текст", а только "Введите" ...

d0rM03D 04.08.2003 19:39

однако так получается... проверял не один раз.

RaZEr 04.08.2003 19:53

Ну тогда ХЗ ... проверь поле в базе, мож длинны мало ...

Aeon 04.08.2003 23:06

d0rM03D
RaZEr прав, твой код должен работать нормально... можешь проверить что у тебя выходит из базы так:
PHP код:

echo '<pre>';
print_r($row);
echo 
'</pre>'

и посмотри что у тебя выходит в $row[2]; если только "Введите", значит проблема со скриптом который вводит этот текст в базу...

d0rM03D 06.08.2003 16:47

Вложений: 1
Прям беда. Привожу _скопированный_ кусок кода со вставкой от Aeon'a:

PHP код:

$request "SELECT ntext, ntitle, date_format(ndate,'%e.%m.%y') as ndate FROM news WHERE id=$id";
$result mysql_query($request) or die(mysql_error());
$row mysql_fetch_row($result);
if (!isset(
$submit)) {
echo 
'<pre>';
print_r($row);
echo 
'</pre>';
echo 
"
<table border=0 align=center>
<form action=changenews.php?archivepage="
.$archivepage."&msg=changed method=post>
<tr><td align=center><b>"
.$row[2]."<br><br>&Acirc;&acirc;&aring;&auml;&egrave;&ograve;&aring; &iacute;&icirc;&acirc;&ucirc;&eacute; &ograve;&aring;&ecirc;&ntilde;&ograve; &iacute;&icirc;&acirc;&icirc;&ntilde;&ograve;&egrave;:</b></td></tr>
<tr><td><input name=ntitle type=text maxlenght=50 size=20 value="
.$row[1]."></tr>
<tr><td><textarea name=ntext cols=50 rows=10 value=>"
.$row[0]."</textarea></tr>
<tr><td align=center><br><input name=submit type=submit value=&Egrave;&ccedil;&igrave;&aring;&iacute;&egrave;&ograve;&uuml;></td></tr>\
<tr><td align=center><br><input name=id type=hidden maxlenght=4 value="
.$id."></td></tr>
</form>
</table>"


и прилагаю скринт с результатом выполнения.

Добавлено через 3 минуты:
Кстати, еще вопрос вдогонку. Хочу включать взависимости от передаваемой GETom переменной включать определенный файл. Сначала хотел использовать if и исходя из переданного значения открывать файл. Но потом подумал, что проще будет использовать такую конструкцию:
PHP код:

if (isset($page) && file_exists("$page.php")) {
include (
"$page.php");
}
else { 
//по умолчанию
include ("что-нибудь.php");


Что есть лучше?

RaZEr 06.08.2003 17:28

Цитата:

и прилагаю скринт с результатом выполнения.
Монтаж, как пить дать ;) ... выложи где-нить ... не поверю пока сам не увижу ... ;)
Цитата:

Что есть лучше?
От случая к случаю ... все зависит от решаемых задач.

d0rM03D 06.08.2003 18:31

RaZEr
хех:), я дурить вас не собираюсь, да и с графикой не умею работать:).
а выложить не смогу - нет пока хоста с мускулом.

Добавлено через 1 минуту:
решаемая задача - меню. в зависимости от нажатого пункта вставляется скрипт раздела.

RaZEr 06.08.2003 18:44

Да понятно, что меню ... проекты разные бывают (по навороченности) ... сойдет и для меню, но используй лучше, не что написал, а:
Код:

<? include (!empty($content) && preg_match('/^\w{1,255}$/',$content) && file_exists($content.'.inc'))?$content.'.inc':'default.inc'; ?>

Aeon 07.08.2003 01:12

d0rM03D
епсть. глюк. попробуй увеличить maxlenght=50 size=20 на скажем 100 и 60... может он просто не показывает... но Razer прав, так не бывает...

d0rM03D 07.08.2003 07:54

вечно у меня все не как у людей:). При добавление новости я делаю всякие проверки:
PHP код:

$ntitle=substr($ntitle,0,25);
        if (empty(
$ntext)) {                          
                            echo 
"А где же новость?";
                exit;
        }
        if (
preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/",$ntitle)) {  
                           echo 
"Только русский, латинский лфавит; подчерк, пробел и цифры";
                exit;
        }
        
$ntext=ereg_replace(" +"," ",$ntext); 
        
$ntext=strip_tags($ntext,"<b><i>");  
        
$ntext=nl2br($ntext); 

Может проблема как-то связана с ними?:confused:

RaZEr 07.08.2003 08:03

Ты же сказал что в базе у тебя именно "Введите текст" ... и print_r вывел именно это ... причем здесь добавление ...

d0rM03D 07.08.2003 08:07

хз, я уже просто не знаю в чем дело...

RaZEr 07.08.2003 08:10

Тфу, ты епт ... кто бы мог подумать:
Код:

maxlenght=50 size=20 value=".$row[1]."></tr>
ты кавычки забыл ;)

Aeon 07.08.2003 08:36

RaZEr
ептыыыыть, а ты ведь прав, паря...

Добавлено через 5 минут:
d0rM03D
меняй
PHP код:

echo "
<table border=0 align=center>
<form action=changenews.php?archivepage="
.$archivepage."&msg=changed method=post>
<tr><td align=center><b>"
.$row[2]."<br><br>&Acirc;&acirc;&aring;&auml;&egrave;&ograve;&aring; &iacute;&icirc;&acirc;&ucirc;&eacute; &ograve;&aring;&ecirc;&ntilde;&ograve; &iacute;&icirc;&acirc;&icirc;&ntilde;&ograve;&egrave;:</b></td></tr>
<tr><td><input name=ntitle type=text maxlenght=50 size=20 value="
.$row[1]."></tr>
<tr><td><textarea name=ntext cols=50 rows=10 value=>"
.$row[0]."</textarea></tr>
<tr><td align=center><br><input name=submit type=submit value=&Egrave;&ccedil;&igrave;&aring;&iacute;&egrave;&ograve;&uuml;></td></tr>
<tr><td align=center><br><input name=id type=hidden maxlenght=4 value="
.$id."></td></tr>
</form>
</table>"


на
PHP код:

?>
<table border="0" align="center">
<form action="changenews.php?archivepage=<?=$archivepage?>&msg=changed" method="post">
<tr><td align="center"><b><?=$row[2]?><br><br>&Acirc;&acirc;&aring;&auml;&egrave;&ograve;&aring; &iacute;&icirc;&acirc;&ucirc;&eacute; &ograve;&aring;&ecirc;&ntilde;&ograve; &iacute;&icirc;&acirc;&icirc;&ntilde;&ograve;&egrave;:</b></td></tr>
<tr><td><input name="ntitle" type="text" maxlenght="50" size="20" value="<?=$row[1]?>"></tr>
<tr><td><textarea name="ntext" cols="50" rows="10"><?=$row[0]?></textarea></tr>
<tr><td align="center"><br><input name="submit" type="submit" value="&Egrave;&ccedil;&igrave;&aring;&iacute;&egrave;&ograve;&uuml;"></td></tr>
<tr><td align="center"><br><input name="id" type="hidden" value="<?=$id?>"></td></tr>
</form></table>
<?php

кстати короткие версии <?=$foo?> работают только если php конфигурирован с опцией short_tags = on. если нет, пиши <?php echo $foo;?>

d0rM03D 07.08.2003 09:39

нда, насколько все просто %)
RaZEr
пасиб огромный!
Aeon

Цитата:

кстати короткие версии <?=$foo?> работают только если php конфигурирован с опцией short_tags = on
енто я знаю:).
Я просто добавил \" вместо того чтобы вставлять html. Или html лучше не выводить через php?

Aeon 07.08.2003 09:47

d0rM03D
дело вкуса больше чем чего-либо иного... я лично предпочитаю такие здоровые блоки через php не пихать, а кидать прямым текстом - нагрузка на сервер немного меньше, да и дебаг делать проще - например эта проблема скорее всего даже не появилась бы если бы php и html писались отдельными блоками... а так сам видишь как бывает, поди разберись где там кавычки не хватает или точка не с той стороны стоит...


Часовой пояс GMT +4, время: 00:35.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.