Посоветуйте как организовать код
Делай ленивые объедки
а в пхп есть ORM-ы ?
Propel + Creole я бы посоветовал автору.
возьмем листочек/ручку, начертим как все примерно будет выглядеть
я уже так раз встречался, прикольно получилось
можно еще по аське, но это долго и токо вечером
Вообще, мне не хватает навыка "хорошего программирования". Как я понимаю, это достигается либо потом-кровью-своими ошибками, либо ценными советами какого-нибудь наставника (например, на работе либо школой (не знаю, преподают ли такое на ВМК? или у нас на вычмате? подозреваю, что нет).
Наверняка ведь есть какие-то прописные истины, которые всем опытным программистом известны? Лично я пока только до одной допёр: "написал одинаковый код три раза - пиши функцию, использовал одинаковую константу три раза - объявляй специальную переменную, и т.п."
Например, можешь почитать фаулера
а потом уже вопросами общей архитектуры кода заниматься.
зы: даже если используешься константу больше НУЛЯ раз в программе, ее следует выносить
Книжку почитаю, спасибо. Возможно, это как раз то что мне нужно.
Моя знать как искать инфа в интернет, однако Фаулеров много, и даже у Мартина Фаулера есть разные книги. И "экстремальное программирование", если ты именно про него, не один Фаулер написал.
У мартина фаулера ещё книжка про архитектуру есть
Ну, есть такие "естественные" константы, как 7 или 12 (дни недели, месяцы). Их, я думаю, выносить не надо.Представляешь, их тоже надо выносить.
Когда в коде где-то там встречается какое-то магическое число 7 - совершенно непонятно, что оно означает, что оно здесь делает, откуда оно взялось. А вот если там написано WEEK_IN_DAYS - то всё сразу становится понятно.
и помнитьничего страшного, память заодно потренируешь
тут был пост о мега крутой среде разработки
Cотри срочно!
вот путь джедая:
сначала тренировка памяти, потом прога на несколько тысяч строк, потом макконнелл и уж после всего этого ИДЕ
чем на говномакконела дрочить.
а то блин, как ни зайдешь в девелопмент, обсуждают уровни абстракции и объектно-ориентированный подход.
А хуле рассказывать, я ж обычный негр, с тем отличием, что плеткой по жопе не бьют, когда негр говорит своему хозяину, что он неправ.
Смысл второго вопроса в том, готов ли ты потратить недельку (или даже две) на разработку небольшого фреймворка, с помощью которого потом удобно и быстро клепать приложения? Просто если приложение надо написать одно и небольшое, то писать ради этого фреймворк - дело неоправданное с точки зрения времени, и, как следствие, финансов.
Даже чтобы самому разобраться, проще посмотреть, как сделано у других.
Свое проще тюнить. И свое неуниверсальное может оказаться лучше, чем не свое универсальное.
Ну фиг знает. Propel я без проблем тюнил, чтобы он с ораклом лучше дружил, а для мускуля его за глаза хватит.
Например, я получаю количество сотрудников, работающих в данный момент в компании. Оно меняется только при добавлении/удалении сотрудника. Поэтому логично положить результаты запроса в кэш (xCache, Apc) и т.п., причем так, чтобы при добавлении/удалении сотрудника данные в кэше стали не валидными. И хочется это не писать кастомно для данного параметра кэша, а как-то "зашить" на уровне фреймворка.
Можно легко затюнить Propel?
А вообще, все зависит от поставленных целей конечно. Например, для разработки клиентской javascript-части мы используем библиотечку jQuery. Конечно, дописываем кое-что, но писать свое не стали. Не возникло потребности. А вот для ORM решили свой сделать. Не на базе другого даже, а просто свой. Просто хочу сказать, что я не являюсь принципиальным противником готовых фреймворков
Могу написать несколько конкретных предложений по организации. Тока сначала вопросов пара есть - используется PHP5? И, это единичный проектик, или есть варианты, что и дальше придется делать что-то похожее?Напиши свои предложения, пожалуйста
php5, наверное, не используется. Я стараюсь писать как можно проще и универсальнее.
Проект - не совсем единичный. В будущем предполагается дописывать какие-то модули.
Конкретно могу такой пример привести: бывают круговые турниры, а бывают "навылет". Сейчас нужно написать всё только для круговых, но в будущем могут потребоваться юзерские и админские интерфейсы для турниров навылет.
Насчёт фреймворков: если я правильно понимаю смысл этого слова, то я использую некоторые сторонние. Для доступа в БД, для рисования простых форм в админке, для построения навигации. Но вот для юзерских интерфейсов фактически пишу всё сам.
php5, наверное, не используется. Я стараюсь писать как можно проще и универсальнее.На php5 будет и проще, и универсальнее в том смысле, что легко потом это использвоать где-то ещё.
А на php4 - универсальнее в том смысле, что есть какие-то дремучие хостеры, у которых до сих пор только php4 (поддержка которого, кстати, афаик уже прекратилась) - это всё равно, что пользоваться сегодня Windows 98.
Сложный метод - поправить прямо в генераторе addDoCount, addDoInsert, addDoDelete, addDoDeleteAll.
А я вообще противник всяческих ORM. Слишком уж часто приходилось заставлять разработчиков использовать написанные вручную SQL-запросы, ибо генерируемые запросы тормозили.
Первый хинт. В пхп5 у класса есть методы __get, __call, __set, с которым можно очень хорошо баловаться. Например, есть объект $a типа A. Если в классе A объявить метод
__get( $Name ) { return $this->data[$Name]; }
Это позволяет создать классы Game и Team, но в каждом из них не объявлять кучу полей - членов класса, а хранить все данные об игре, скажем, в массиве $data, при этом получая их удобным образом типа $game->GameName, или $game->getGameName и т.п.
Кроме того, этот функционал одинаков для классов Game и Team, т.к. он общий. Поэтому его можно вынести в абстрактного родителя - класс DbObject.
Второй хинт. Теперь надо научить класс DbObject поднимать данные из базы и складывать их в массив $data, ну и хочется также научить этот класс сохранять данные в базу.
Совсем простое решение написать статический метод в DbObject вида
static get( $sql, $ClassName ) {
// выполнить данный sql-запрос
// на каждую строчку полученную создать объект типа $ClassName - наследник DbObject и заполнить его массив $data данными из строчки
// вернуть массив объектов.
}
Изъян (и преимущество) в том, что придется все равно руками в коде написать sql-запрос. Иногда это выгодно, иногда рутинно и не хочется.
Можно (потребует больше усилий) создать возможность в DbObject хранить мета-данные о таблице, с которой он работает, достаточные для того, чтобы он сам формировал запрос. Но лучше не отдавать это на полную автоматику.
Третий хинт. Что делать с полями-ссылками. Сначала рассмотрим ситуацию один-ко-многим. У игры Game есть поле referee_id. Можно добиться того, чтобы метод $game->getReferee возвращал объект Referee, делая запрос в базу данных. Причем этот функционал можно реализовать в опять же в DbObject. НО. Тогда возникает проблема с отображением списка игр - ведь там нужна фамилия игры, а если доставать судей последовательно для каждой игры, то может уйти и 50 запросов в базу. Это можно решить следующим образом: написать хелпер-метод (статическую функцию, если угодно которая поднимает одним запросом судей по данным играм примерно с такой сигнатурой вызова
fillReferenceObjects( $games, 'Referee' )
Опять же, функция может быть реализована полне абстрактна (там надо додумать еще параметры, конечно).
Четвертый хинт. Много-ко-многим. Продолжим пример с судьями. Судья-то в игре не один. Итак, есть таблица вида game_id, referee_id. И хочется вызывать метод $game->getReferees и получать массив объектов Referee. Поможет та же функция, что и выше, только реализация будет другая для случая много-ко-многим.
Заключение. В изложенной выше схеме еще много степеней свободы. Можно ее сделать ближе к ORM с автогенерацией запросов (но я бы так делать не стал можно просто сделать удобнее за счет грамотной организации методов. Основная цель схемы выше - вынести функционал по подъему/сохранению объектов в бд в общее место, сделать его абстрактным. Плюс добиться того, чтобы в объектах-наследника DbObject код практически был не нужен. Это избавляет тебя от кучи рутинной работы.
Да, насчет жизненности. Такую схему я сореализовывал (реализовывал в команде). Получилось удобно и работоспособно.
Поскольку все очень абстрактно, то, если есть вопросы, готов пояснить любое место.
Это позволяет создать классы Game и Team, но в каждом из них не объявлять кучу полей - членов класса, а хранить все данные об игре, скажем, в массиве $data, при этом получая их удобным образом типа $game->GameNameЭто плохой подход - потому что допускает опечатки вроде $game->GaneName, которые будут отловлены только во время работы, если вообще будут отловлены (они же всего-навсего notice сгенерируют).
Можно (потребует больше усилий) создать возможность в DbObject хранить мета-данные о таблице, с которой он работает, достаточные для того, чтобы он сам формировал запрос.По крайней мере, можно сделать метод, который будет грузить нужный объект по Id, во многих случаях нужно будет именно это.
А снаружи - брать нужный объект (с известным Id) из реестра.
Ну и можно тогда ещё и ленивую загрузку осуществить для таких объектов.
Это плохой подход - потому что допускает опечатки вроде $game->GaneName, которые будут отловлены только во время работы, если вообще будут отловлены (они же всего-навсего notice сгенерируют).
Я бы согласился, если бы это был не пхп, а что-нибудь компилируемое. С таким же успехом в пхп можно написать не $game, а $gane. "Волков бояться - в лес не ходить" А еще, если сначала зарегистрировать все допустимы поля (а так и надо сделать то в __get можно плевать исключение на кривое название. А вот $gane действительно только нотис дает. Так что мое предложение лучше, чем то, что предлагает нам сам пхп.
С таким же успехом в пхп можно написать не $game, а $ganeЕсли писать в блокноте.
А если писать в IDE - то хрен ты опечатаешься в имени переменной, метода или члена.
А вот $gane действительно только нотис даетКогда ты попытаешься вызвать у него какой-нибудь метод или взять член - будет Fatal Error.
Спасибо, буду ботать и разбираться.
я так и не понял, что она делает:
самое забавное, что она откуда-то мигрировала, т.к. в скриптах нигде не используется.
заметь, вполно нормальные константы.
7 - наверно дни недели
100 и 400 для определения весокосного года, наверно.
13 и 14 это 12+1 и 12+2(чтоб враги не догадались (С) )
function dow($d, $m, $y)
{
$m2 = $m;
if($m == 1)
{
$m2 = 13;
$y = $y-1;
}
if($m == 2)
{
$m2 = 14;
$y = $y-1;
}
$val4 = intval$m2+1)*3)/5);
$val5 = intval($y/4);
$val6 = intval($y/100);
$val7 = intval($y/400);
$val8 = $d+($m2*2)+$val4+$y+$val5-$val6+$val7+2;
$val9 = intval($val8/7);
$val0 = $val8-($val9*7);
return $val0;
}
какая-то баянистая формула похоже, придуманная когда флоатов ещё небыло или были они дорогими.
Оставить комментарий
arturabramian
Php, база в mysql. В базе в разных таблицах хранятся объекты, сейчас мне нужно напрогать всяких функций, чтобы один из этих объектов разными способами выводить на сайт. Конкретнее, нужный мне объект - это игра (спортивная). В базе хранятся следующие данные об игре:турнир
время проведения
команды (названия, точнее их id)
счёт
составы команд (вынесены в отдельную таблицу, связывающую id игры с id принимавших участие игроков)
судьи
и т.д.
При этом вся инфа в разных таблицах, связь между таблицами по id. То есть, чтобы узнать фамилию судьи, нужно сначала из таблицы с играми по id игры определить id судьи, а потом из таблицы с судьями узнать его фамилию.
В разных местах сайта нужно выводить разную информацию об игре. Здесь - турнир и названия команд, там - составы, ещё где-нибудь - счёт и дату, и т.п.
Все нужные функции и запросы я в состоянии написать, но у меня есть сомнения в том, что я выбираю оптимальный способ организации кода. Сейчас я думаю делать так: пишем класс game, объявляем в нём дохрена переменных, в которых будет храниться вся-вся информация об игре, собранная из разных таблиц БД, какая только может потребоваться. Пишем разные функции, которые будут из этих переменных составлять нужные мне строковые переменные, чтобы я их засовывал на сайт куда надо.
Вопрос в том, как заполнять переменные с информацией об игре. Можно на каждую группу переменных писать свою функцию, заполняющую данные из базы:
function get_players{
// query to get players having game id
...
// fill the $players array with this data
...
}
function get_teams{...}
function get_score{...}
и т.д. В этом случае, если мне потребуется вывести в одном блоке всю информацию об игре, прога сделает дохрена запросов, чтобы всю инфу последовательно из базы выцепить. Я примерно посчитал, получается что сейчас всю (вообще всю) инфу об игре можно вытащить из базы пятью запросами, а при таком подходе, когда мы по кусочкам вытягиваем, общее количество запросов будет порядка двадцати.
Другой вариант - это с самого начала, где-нибудь ещё в конструкторе, проинициализировать все переменные из базы. Т.е. сразу знать об этой игре всё что только можно. Но тогда обратная ситуация: допустим, мне в каком-то месте нужна только информация о командах, а я создаю здоровенный класс, набираю в него кучу данных- о турнире, об игроках, - а использую только малую часть из этого.
Если я буду рисовать турнирную таблицу, то потребуются данные о 50 играх. Хочется такой код, чтобы работало побыстрее. Как я понимаю, множественные запросы влияют на скорость? Или, если запросы маленькие (обрабатывается небольшое число записей, порядка десяти то на количество запросов можно забить?
Что скажут отцы пхп? Может, есть какой-то достаточно универсальный подход к тому, как организовывать хранение и обработку такого рода данных в проге, чтобы было удобно и быстро работало?