Помогите исправить собственное быдлокодерство

gray

Новичок
Не могу допедрить как сделать более элегантно.
Суть такая. Нужно брать из БД перечень цифр и загонять каждую строку из бд в свою константу.
Сделал так. Понимаю что можно сделать в 2-3 строки.

PHP:
$query="SELECT GROUP_CONCAT(CAST(`t1`.`id` AS CHAR)) as groupName FROM `users` `t1` WHERE `t1`.`group_id`>'0' GROUP BY `t1`.`group_id`;";
		$result=mysql_query($query) or die ("Ошибка выполнения запроса к БД: ".mysql_error());
		//$arr=array("_ID_MANAGERS_","_ID_STOREKEEPER_","_ID_LOGIST_","_ID_ADMIN_","_ID_SUPERADMIN_");
		$row = mysql_fetch_assoc($result);$isManager=$row['groupName'];	$row = mysql_fetch_assoc($result);$isStorekeeper=$row['groupName'];
		$row = mysql_fetch_assoc($result);$isLogist=$row['groupName']; $row = mysql_fetch_assoc($result);$isAdmin=$row['groupName'];
		$row = mysql_fetch_assoc($result);$isSuperadmin=$row['groupName'];
		define("_ID_MANAGERS_", $isManager); define("_ID_STOREKEEPER_", $isStorekeeper); define("_ID_LOGIST_", $isLogist); define("_ID_ADMIN_", $isAdmin);
		define("_ID_SUPERADMIN_", $isSuperadmin);
upd: исправлен запрос
PHP:
SELECT GROUP_CONCAT(CAST(`t1`.`id` AS CHAR)) as groupName FROM `users` `t1` WHERE `t1`.`group_id`>'0' GROUP BY `t1`.`group_id` ORDER BY `t1`.`group_id`;
 

Вурдалак

Продвинутый новичок

gray

Новичок
Константы выбраны из-за:
- эти строки один раз считываются из БД и многократно используются в скрипте. в процессе выполнения скриптов они не меняются.
- строки доступны во всех областях видимости.
 

Фанат

oncle terrible
Команда форума
И что тебе мешает сделать присвоение в цикле, беря имена констант из массива?
 

gray

Новичок
Не могу понять как мне в цикле
PHP:
 while ($row = mysql_fetch_assoc($result)) {
			define("/*нужный эл-т массива $arr*/", $row['groupName']);
		}
обращаться всякий раз к следующему эл-ту массива
PHP:
$arr=array("_ID_MANAGERS_","_ID_STOREKEEPERS_","_ID_LOGISTS_","_ID_ADMINS_","_ID_SUPERADMINS_");
 

Вурдалак

Продвинутый новичок
Ты ведь в курсе, что порядок записей может взять и поменяться, правда?
 

gray

Новичок
Ты ведь в курсе, что порядок записей может взять и поменяться, правда?
Ты о каком порядке записей? Выборка из БД?
Нет, их порядок не должен меняться.

Офф: Вурдалак. Два комментария от тебя, а информации полезной мало. Конкретное что-то можешь сказать?
 

gray

Новичок
Ты с ними договорился?
Фанат, данные группируются по возрастанию.
первая группа цифр собрана вокруг идентификатора 100 (22,24,26,65,78). Вторая вокруг 200 (11,45,67,23). Треться 300 (1,54,41) и т.п.
Т.е. первым выводится строка с группы 100, потом 200, затем триста. Так что ни одной цифры в группе не будет, такого нет.
 

Вурдалак

Продвинутый новичок
Нет, их порядок не должен меняться.
Во-первых, порядок может запросто быть другой, поскольку нет ORDER BY и нет никакой гарантии. Группировка и сортировка — разные вещи.
Во-вторых, порядок следования групп, если просто подумать, гораздо более изменчивая информация, чем её id. Т.е. ты грубо хочешь захардкодить группы, основываясь на их порядке следования. Тебе надо просто прописывать в константы тупо числа и выкинуть нафиг код с БД.
В-третьих, опыт общения на этом форуме показывает, что говорить что-то конкретное (читай: сразу описание всех ошибок) — занятие неблагодарное и порой становится ясно, что тратишь время зря, поэтому я часто прибегаю к довольно ленивому указанию ошибок.
 
  • Like
Реакции: gray

gray

Новичок
Вурдалак
1. Спасибо. Действительно ORDER BY пропустил.
2. Эти числа хранятся именно в БД. Потому оттуда и беру.
Краткий ликбез: Собственно цель и задача написать кусок кода, который проверяет привязанность пользователя к группам пользователей без регулярного обращения к БД. Изначально были написаны функции, которые при каждом обращении к ним кидались в БД с целью выяснить привязаны ли пользователь к оной группе или нет. Переписываю таким образом, чтобы обращение к БД произовдилось один раз в начале скрипта, а потом проводилась проверка, есть ли эта цифра в перечне или нет. Собственно отсюда и константы.
Да, наверное то что я считаю что первая строка выборки из БД всегда будет перечень ид менеджеров, это выглядит не очень хорошо. Но пока не могу придумать как это сделать так, чтобы не обращаться к БД каждый раз с where `t1`.`group_id`=100 (200,300 и т.п.). Хочу сделать все в одном запросе. Но не понимаю как, потому и обратился на форум.
3. Вурдалак. Несмотря на то, что зарегистрирован тут давно, у меня нет большого опыта общения на этом сайте и если есть какие-то негласные правила, то я их к сожалению не знаю. Возможно помогать новичкам на форуме - занятие неблагодарное. Но еще более неблагодарное дело, давать комментарии которые у людей с меньшим уровнем знания php вызывают еще больше вопросов и недоумения.
Ты помог уже тем, что указал на пропущенный ORDER BY, быть может появится человек, который еще в чем-то поможет что я не вижу.
Тебе спасибо.
 

damner2

Новичок
Во-первых, порядок может запросто быть другой, поскольку нет ORDER BY и нет никакой гарантии. Группировка и сортировка — разные вещи.
Не совсем :)
В Mysql, если указан GROUP BY, то строки сортируются по полям, по которым идёт группировка.
Нет смысла писать ORDER BY с таким же набором полей, как и GROUP BY.

http://dev.mysql.com/doc/refman/5.5/en/select.html
If you use GROUP BY, output rows are sorted according to the GROUP BY columns as if you had an ORDER BY for the same columns.
 

gray

Новичок
damner2 Ага, спасибо. Для 5.1. тоже актуально.

Мужики, подскажите как мне в цикле каждому эл-ту существующего массива $arr назначать строку выборки БД. Задача ведь тривиальная, уверен что настолько простая и очевидная что решается в одну две строчки. Но сообразить все равно не могу как. Подскажите логику или php-функцию, которая поможет разобраться.
 

damner2

Новичок
gray
Тебе нада:
1. Сделать функцию для проверки, входит ли пользователь в группу.
2. Сделать в ней статичную переменную (http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static), в которую будут загружаться все данные из БД (какой пользователь в какой группе), если они ещё не были загружены.
3. Когда нужно проверить, входил ли пользователь в группу, то должна вызываться эта функция с двумя параметрами (группа, пользователь), и не должны объявляться никакие константы.
 

gray

Новичок
damner2
Не мне такой вариант не подходит.
Функции написаны.
Было:
PHP:
function isManager($id)
	{
		...
		$query="SELECT client_id,group_id from users WHERE id='".$id."' LIMIT 1";
		$result=mysql_query($query) or die ("Ошибка выполнения запроса к БД: ".mysql_error());
		while ($row = mysql_fetch_assoc($result)){
			if($row[group_id]==100) return true;
			else return false;
		}
	}
стало
PHP:
function isManager($id)
	{
		$digits = explode(',',_ID_MANAGERS_); if (in_array($id, $digits)) return true; else false;
	}
В _ID_MANAGERS_ идут числа через запятую, которые нужно взять из БД.

Естественно стало короче и быстрее.
Теперь задача грамотно забить эти самые константы.
Вариант который я написал работает, но мне он не нравится. Какой-то кособокий.
PHP:
$query="SELECT GROUP_CONCAT(CAST(`t1`.`id` AS CHAR)) as groupName FROM `users` `t1` WHERE `t1`.`group_id`>'0' GROUP BY `t1`.`group_id`;";
        $result=mysql_query($query) or die ("Ошибка выполнения запроса к БД: ".mysql_error());
        //$arr=array("_ID_MANAGERS_","_ID_STOREKEEPER_","_ID_LOGIST_","_ID_ADMIN_","_ID_SUPERADMIN_");
        $row = mysql_fetch_assoc($result);$isManager=$row['groupName'];    $row = mysql_fetch_assoc($result);$isStorekeeper=$row['groupName'];
        $row = mysql_fetch_assoc($result);$isLogist=$row['groupName']; $row = mysql_fetch_assoc($result);$isAdmin=$row['groupName'];
        $row = mysql_fetch_assoc($result);$isSuperadmin=$row['groupName'];
        define("_ID_MANAGERS_", $isManager); define("_ID_STOREKEEPER_", $isStorekeeper); define("_ID_LOGIST_", $isLogist); define("_ID_ADMIN_", $isAdmin);
        define("_ID_SUPERADMIN_", $isSuperadmin);
Но как его через цикл описать я не могу допедрить.
 

damner2

Новичок
gray
Не, задачу "грамотно забить эти самые константы." я помогать решать не буду - это неправильный подход :)

Оставь как есть, если для тебя вариант работает.
Переписывание твоего варианта с 7 на 3 строчки не сделает твой код хорошим - в нём и так очень много "говнокода" (в тех 15 строках, которые ты написал тут).
 

Фанат

oncle terrible
Команда форума
Естественно стало короче и быстрее.
короче чем что?
вызов функции как был коротким - так и остался. А что у нее внутри - не всё ли равно?
быстрее чем что?
нужна ли тебе быстрота ценой говнокода? нужна ли она здесь вообще? Нельзя ли добиться того же другим способом (о котором внезапно! написал damner2)?
 

Фанат

oncle terrible
Команда форума
Кстати, по поводу короче
PHP:
function isManager($id)
{
    global $db;
    return $db->getOne("SELECT 1 from users WHERE group_id=100 AND id=?i",$id);
}
если пользоваться нормальными функциями для работы с БД, а не говнокодом
 

gray

Новичок
Фанат
функция isManager вызывается не так часто. а вот аналогичная ей функция isClient вызывается на некоторых страницах сотни раз. Естественно обращение к БД получается тяжеловесным.
Я видимо не сделал на этом акцент.

В коде есть частые проверки на то, кому принадлежит пользователь. или кому принадлежат его items. все это делается через if(isAdmin($userId)||isSuperAdmin($userId)){}
Собственно вывод страницы теперь идет доли секунды, против 3-х секунд до этого.
Вы все время толкаете меня к тому, что я должен переделать функцию так чтобы каждый раз обращался к БД. А я наоборот хочу от этого избавиться. Одна функция делает изначально все операции выборки. Один раз. Единожды. Пихает это в глобальные перменные или, как я хочу сделать, в константы.
А в дальнейшем я только обращаюсь к этим функциям (isManager(), isAdmin()) для того чтобы получить true\false на вопрос есть ли в _ID_MANAGERS_ или в _ID_ADMINS_ искомая цифра или нет.

Мне не нужна помощь в переделки этой функции. Я прошу вас помочь в том, как мне выборку из БД $result, которая имеет предположим такой вид:
Первая строка: 22,12,11,14,44 итп
Вторая строка; 21,23,45,34 итп
Третья строка: 46,25,77...
И т.п.
Забить в цикле в константы или глобальные переменные, наименования которых содержатся в массиве:
PHP:
$arr=array("_ID_MANAGERS_","_ID_STOREKEEPERS_","_ID_LOGISTS_","_ID_ADMINS_","_ID_SUPERADMINS_");
Это всё в чем я прошу помочь...
Мужики, ну в самом деле, вы чего? )
 

AmdY

Пью пиво
Команда форума
gray
так забей это туда же в базу.
PHP:
//будет что-то типа 
$query = "SELECT GROUP_CONCAT(CAST(`t1`.`id` AS CHAR)) as groupName, groupRole FROM `users` `t1` WHERE `t1`.`group_id`>'0' GROUP BY `t1`.`group_id`;";
$result = mysql_query($query) or die ("Ошибка выполнения запроса к БД: " . mysql_error());
//$arr=array("_ID_MANAGERS_","_ID_STOREKEEPER_","_ID_LOGIST_","_ID_ADMIN_","_ID_SUPERADMIN_");
while($row = mysql_fetch_assoc($result)) {
    define('_ID_'.$row['groupRole'], $row['groupName']);
}
 
  • Like
Реакции: gray
Сверху