ограничение php не работает в цикле mysql_fetch_array - PullRequest
0 голосов
/ 03 апреля 2011

Я хочу, чтобы мою статью базы данных переклассифицировали.Я анализирую текст данной статьи, а затем проверяю, есть ли одно слово статьи, совпадающее с тегом 1, которое встречается в таблице категорий, а затем обновляю эту статью под этим именем категории.Мой код здесь.Я хочу сделать ограничение, чтобы в каждой категории максимум было 5 статей.но ограничение обновления не работает.Спасибо.

<?php
header('Content-type:text/html; charset=utf-8');
$db = mysql_connect("localhost","root","root") or die("can not connect Mysql Server");
mysql_select_db("12",$db);
$result = mysql_query("SELECT title,content,id,cat,date FROM articles Order By date DESC"); //get all the articles
$count = 0;
$ids = array();
$categories = array('1','2','3','4','5','6','7','8','9','10');//category numbers, for 1 = art, 2 = travel... these are stored in another refrenced DB table
$curCategory = array_shift($categories);
echo $curCategory;
while ($row = mysql_fetch_array($result))
{
$tt = $row['title'].'&nbsp;'.$row['content'];
$tt = preg_replace('/[^a-zA-Z0-9 ]/','',$tt);
$words = preg_split("/\s+/",$tt);   
$uniqueWords = array_keys(array_flip($words)); // broken article sentence into words
$parts = '';
foreach($uniqueWords as $word){     
$parts[] = " tag1 = '$word' OR tag2 = '$word' OR tag3 = '$word' OR tag4 = '$word' OR tag5 = '$word' ";   
} 
$where = implode(" OR ", $parts);
mysql_select_db("12",$db);
mysql_query("SET NAMES utf8");
    $query1 = mysql_query("SELECT count(*) as count FROM tag1 WHERE ($where) AND category ='count($categories)' ");  //put the break words into reference table match out the category number
    $count = 0;
    while ($row = mysql_fetch_array($query1)) {
        $count = $row['count'];
    } 
    if($count) {
        $ids[] = $row['id'];
        $count++;
        if($count == 5) {
             mysql_query("UPDATE articles SET cat = '$curCategory' WHERE id in ('".implode("', '", $ids)."')"); //update every category max articles 
            if(!$curCategory = array_shift($categories)) {
                break;
            }
            $count = 0;
            $ids = array();
        }
    }
}
?>

справочная таблица

category | tag1    | tag2   | tag3       | tag4    |  tag5  
1        | paint   | picture| sculpture  | photo   |  bronze   
2        | tourism | travel | tour       | journey |  trip
3        | style   | vogue  | fashion    | mode    |  Popular
... // 10 categories, category 1 = art , category 2 = travel ...

Ответы [ 4 ]

2 голосов
/ 06 апреля 2011

Очень очень странный код.НО ... $ids[] = $row['id']; - ваш sql не имеет столбца id, поэтому никаких идентификаторов в результате.Возможно, потому что вы используете $row как во внешнем, так и во внутреннем циклах - вот в чем проблема.

Кроме того, вы понимаете, что статья с 100 уникальными словами (не так много, верно?) Формирует SQL-запрос с 500 * 1006?*?:)

А как насчет mysql_select_db и mysql_query("SET NAMES utf8"); - почему они в цикле, ПОЧЕМУ?

0 голосов
/ 13 апреля 2011

Страшно.

Код не совсем понятен, как хорошо объясняют другие ответы, но выбор структуры для данных тега также может вызвать проблемы.

Вместо 5 столбцов для5 тегов, создайте отдельную таблицу тегов и свяжите ее со своими статьями:

article | tag       |
  1     | paint     |
  1     | picture   |
  1     | sculpture |
  1     | photo     |
  1     | bronze    |
  2     | tourism   |
  2     | travel    |
  2     | tour      |

Затем, когда вы тегируете, вам не нужно беспокоиться о том, является ли тег тегом tag1 или tag2, или тег tag3 равен NULLили вы передумали и хотите 6 тегов в конце концов.Структура будет работать в любом месте от 0 до любого количества тегов, делая бит «частей» в запросе примерно таким:

$parts = " tag in ('"
        .implode($uniqueWords,"', '")
        ."')";
// e.g. if uniqueWords = ['one','two','three'], $parts= "tag in ('one','two','three','')"

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

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

Разнесите вашу статью и при поиске уникальных слов подсчитайте вхождения в слова, за исключением распространенных английских слов, таких как "the".Затем отсортируйте уникальные слова в порядке появления, в первую очередь наиболее повторяющиеся слова.У вас есть список основных слов в вашей статье, возьмите первые пять, это теги.Вставьте в таблицу.

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

tagstable - 1 column "tag" is the PK
| paint     |
| picture   |    articlewordstable - 1 column "word" is the PK - empty     
| sculpture |    | -   | 
| photo     |    | -   |     
| bronze    |

Вставьте токенизированные слова в articlewordstable.Затем сделайте запрос к таблице, объединяющейся с тегами:

SELECT word FROM articlewordstable
INNER JOIN tagstable
ON tag = word;

, вы получите список слов, которые также являются тегами.Вы можете установить ограничение в 5 результатов, вы также можете сделать

SELECT word, count(word) occurrences FROM articlewordstable
INNER JOIN tagstable
ON tag = word
GROUP BY word
ORDER BY occurrences DESC;

, что даст вам наиболее часто используемые слова, которые также появляются в вашем списке тегов.Это также может быть ограничено до 5, а затем использовать по своему усмотрению.

Надеюсь, это поможет!

0 голосов
/ 06 апреля 2011

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

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

Меня поразило несколько проблем, и я перечислю их здесь:

  • Вы даже проверите руководство, чтобы увидеть, правильно ли вы используете функцию
  • вы выбираете одну и ту же базу данных дважды (mysql_select_db('12',$db));
  • Вы создали статический массив категорий, а затем удалили первый элемент. Почему?
  • вы используете array_keys(array_flip($words)); вместо array_unique
  • Вы неправильно используете переменную count, вы просто перезаписываете ее, когда я считаю, что вы хотите увеличить ее
    • Для этого вы можете использовать mysql_result('count',$query).
  • Откуда взялся идентификатор в базе данных ($ids[] = $row['id'];) << WTF </li>

И, честно говоря, остальная часть кода слишком запутана, и вы даже не поняли, похоже, вы скопировали куски кода из Интернета и скрестили пальцы на мне.

Также я очень удивлен, что у вас есть 50 очков, которые вы можете предложить в качестве награды.

0 голосов
/ 06 апреля 2011

Давайте проанализируем этот код:

// this query returns one row with column `count`, you're comparing column
// `category` to the literal string `count($categories)` where
// `$categories` is an array of numbers and therefore evaluates to `count(Array)`
$query1 = mysql_query("SELECT count(*) as count FROM tag1 WHERE ($where) AND category ='count($categories)' ");
$count = 0;
// warning: overwriting previous $row variable
while ($row = mysql_fetch_array($query1)) {
    // an if($row=...) is better since you've on row anyway
    // Contents of $row = array( 'count' => NUMBER );
    // You're overwriting $count with the number of found articles
    $count = $row['count'];
}
// unless the query failed or there are no articles found, the next condition is true
if($count) {
    // undeclared variable $ids; $row['id'] does not exist since it is overwritten
    $ids[] = $row['id'];
    // The next lines do not limit the number of updates, it only updates
    // if $count == 4; where $count is the number of articles in a category
    $count++;
    if($count == 5) {
         mysql_query("UPDATE articles SET cat = '$curCategory' WHERE id in ('".implode("', '", $ids)."')");
        // so if the current catgeory has five articles, quit?
        if(!$curCategory = array_shift($categories)) {
            break;
        }
        // otherwise, reset for the next category
        $count = 0;
        $ids = array();
    }
}

Вы должны обязательно взглянуть на свой код и посмотреть, все ли вы понимаете. Я уверен, что перезапись $row не предназначена, как и ваш запрос в $query1. При именовании ваших переменных сделайте их более наглядными. Например, используйте $catCount_row вместо $row. Обратите внимание, что вы перезаписываете $count каждый раз, возможно, вы хотите убрать это из цикла while.

Если количество статей не достигнет 4, обновление не будет выполнено.

...