Распечатать статью

Классы в PHP3

Когда достаём из базы данных много подобной информации мы её конечно же в массив оформляем. Если нам надо блок разнотипной информации как одно целое хранить и обрабатывать — создаём объект, используя описание класса как трафарет. Ну а если подобных объектов несколько — массив обектов. Как такую штуку запустить попробую показать.

Например стоит старинная задача: из пункта «А» доехать в пункт «В» на автобусе. Всего автобусных маршрутов в городке — 34, остановок по городку — 99, в некоторые дни отдельные маршруты не ходят. Но вся информация имеется в базе данных и организована следующим образом:
table commonid int(4) name varchar(100)
1 Academic I
2 Anthony Seeger
3 Ashby Crossing
4 Blue Ridge Dr. @ Madison Manor
5 Blue Ridge Hall
… …
98 Waterman Square
99 Zane Showker Hall

В этой таблице перечисленны ID остановок ( int ) и их названия ( string )
table common_2id_stop int(4) routes_string (varchar(250)
1 ;9;10;11;12;
2 ;5;6;6a;7;7a;9;
3 ;4w;7;7a;10;12;
4 ;2;
… …
98 ;3;
99 ;1;2;4;4w;5;6;6a;7;7a;9;7a;10;12;

Здесь показано на какой остановке — её ID ( int ) какие маршруты останавливаются ( string )
table routesprogr_name varchar(10) real_name varchar(10) sunday varchar(10) monday varchar(10) tuesday varchar(10) wednesday varchar(10) thursday varchar(10) friday varchar(10) saturday varchar(10)
01 1 n y y y y y y
02 1w y y y y y y y
03 2 n y y y y y y
04 2w y y y y y y y
… … … … … … … … …
33 12_1 y y y y y y y
34 12_2 y y y y y y y

Показывает програмное имя маршрута ( string ), его реальное имя ( string ) и в какой день недели этот автобус ходит, а в какой нет ( начинаем с воскресенья )

и по каждому маршруту у нас имеется таблица rt01, rt02, …, rt34 ( приведу пример лишь для первого маршрута )
table rt01curent int(4) stop_name int(4) time_string varchar(250)
1 26 ;7:00;8:00;9:00;10:00;11:00;12:00;13:00;14:00;
2 91 ;7:03;8:03;9:03;10:03;11:03;12:03;13:03;14:03;
3 54 ;7:07;8:07;9:07;10:07;11:07;12:07;13:07;14:07;
4 69 ;7:11;8:11;9:11;10:11;11:11;12:11;13:11;14:11;15:
… … …
24 99 ;7:49;8:49;9:49;10:49;11:49;12:49;13:49;14:49;
25 26 ;7:51;8:51;9:51;10:51;11:51;12:51;13:51;14:51;

где показан порядковый номер остановки ( int ) , ID этой остановки ( int ) и строка ( string ) в которой перечисленно время в которое данный автобус останавливается на каждой остановке.

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

Вытаскиваем ( из базы данных ) все автобусы останавливаюшиеся на остановке start. Смотрим, а можем ли добраться на каком нибудь из них до остановки finish? Выдаём информацию, далее смотрим все автобусы останавливающиеся на остановке finish ( не совпадающие с первым запросом ) и смотрим, а где же можем пересесть на эти автобусы с тех, что идут с остановки start. Выдаём результат. Вроде всё просто, но запутаешься во всех этих переменных. И другое дело если есть объект, который хранит всю информацию о маршруте, и другой объект, хранящий всю информацию о автобусной остановке, который содержит массив объектов первого типа — маршруты. Классы, по которым будем создавать эти объекты назовём Route — маршрут, Bus_stop — остановка.

Получается что нам надо создать две переменных типа Bus_stop — одна на остановку start и одна на остановку finish. Ну а колличество объектов типа Route в каждом объекте типа Bus_stop будет определяться колличеством останавливающихся на этой остановке маршрутов. При данном подходе оперируем на уровне объектов, то есть переменных немного и всё наглядно. При необходимости вытаскиваем нужную информацию из объекта.

Ну а как это работает:

Файл choice.php3

$db = mysql_connect(«localhost», «root»);
mysql_select_db(«BUS_STOP»,$db);
$sql=»select name from common «;
echo «»;
echo «»;
echo »

Enter where are you Enter Destination
«;
$result = mysql_query($sql,$db); //выбрали имена остановок из ДБ

echo «»; while($myrow=mysql_fetch_row($result)) { echo «»;
echo «

«;
$result = mysql_query($sql,$db); //выбрали имена остановок из ДБ
echo «»; while($myrow=mysql_fetch_row($result)) { echo «»;
echo «

«;
mysql_close();
?>

генерит картинку

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

find.php3
include «functions.php3″;
echo »
Need from: $place_is To: $place_targ «;
$day=get_day();
echo»     DAY — $day»;
get_result($place_is, $place_targ);
?>

с которым то же всё просто — выдать на экран некоторую контрольную информацию — день недели и запустить собственно программу get_result(…). Основной код — в файле functions.php3.

Функция get_result($start, $finish) открывает базу данных и создаёт две переменных типа Bus_stop.
$db = mysql_connect(«localhost», «root»);
mysql_select_db(«BUS_STOP»,$db);
$routes_start=new Bus_stop($start, $db);
$routes_finish=new Bus_stop($finish, $db);
mysql_close();

При создании каждой переменной этого типа запускается constructor, извлекаеся нужная информация об этой автобусной остановке из базы данных, с помощью вспомогательной функции cut_str(…) строка,где перечисленны все останавливающиеся здесь автобусы, разделяется на составляющие и в результате получаем массив названий автобусов,которые останавливаются на этой остановке.
function Bus_stop($name, $db) {
$this->name_busstop=$name;
$sql=»select id_stop, routes_string»;
$sql=»$sql from common_2, common»;
$sql=»$sql where name=’$name’ and id_stop=id»;
if ($result = mysql_query($sql,$db)) {
$que=mysql_fetch_row($result);
$que[]=mysql_num_rows($result); //last element for control
}
$this->id_busstop=(int)$que[0];
$real_n=cut_str($que[1]); //get all real names for routes stoped

После чего контрольный вывод этих самых имён. Теперь в цикле создаём объекты типа Route и упаковываем их в массив
for($ll=0; $ll<$k;$ll++) {
$this->route[$ll]=new
Route($real_n[$ll],$db);
$this->number_routes++;
}

Tак же constructor класса Route получает имя маршрута и по нему, извлекая нужную информацию из базы данных, создаёт объект — переменную этого типа.
function Route($name, $db) {
global $day_now;
$sql=»select prog_name, $day_now»;
$sql=»$sql from routes»;
$sql=»$sql where real_name=’$name'»;
if($result = mysql_query($sql,$db)) {
$que=mysql_fetch_row($result);
$que[]=mysql_num_rows($result); //last element for control
}
$this->name_route=(string)$name;
$this->id_route=$que[0];
$this->rout_today=(string)$que[1];
if($que[1]==»y») { //do you have this rout today ?
$sql=»select stop_name, time_string»;
$sql=»$sql from rt$que[0]»;
if($result = mysql_query($sql,$db)) {
$k=0;
while ($myrow = mysql_fetch_row($result)) {
$r_stop[$k]=(int)$myrow[0];
$r_times[$k]=$myrow[1];
$k++;
}
$this->rout_stop=$r_stop;
$this->rout_times=$r_times;
$this->number_stop=$k;
}
}
}
В итоге имеем две переменных — $routes_start содержит всё о остановке start, другая $routes_finish о остановке finish.

Теперь, для поиска автобусов, на которых можем добраться от start до finish, вызываем функцию find_direct(…) принадлежащую объекту остановки start, передав в неё ID остановки finish. Ну и смотрим, есть ли у маршрутов, на которые мы можем сесть на остановке start остановка на которую нужно попасть, но важно чтоб она была после того как мы сядем, поскольку марщруты в основном кольцевые и возвращаютсядругой дорогой. Если есть такая, то нужная информация извлекается из объекта и выдаётся пользователю.
function find_direct($id_stop_finish) {
$find=0;

for($i_rout=0; $i_rout<$this->number_routes; $i_rout++) {
$this_rout=$this->route[$i_rout];
if($this_rout->rout_today == «y») {

$numb_stop=$this_rout->number_stop; // for this route
$arr_id=$this_rout->rout_stop;
$i_stop_start=0;
do {
$id_bst=$arr_id[$i_stop_start];
if($id_bst == $this->id_busstop) break;
$i_stop_start++;
} while($i_stop_start<$numb_stop);
$i_stop_finish=$i_stop_start;
do {
$id_bst=$arr_id[$i_stop_finish];
if($id_bst == $id_stop_finish) {
$id_first=$this->id_busstop;
$id_second=$id_stop_finish;
$name_rout=$this_rout->name_route;
$all_time=$this_rout->rout_times;
$time_start=$all_time[$i_stop_start];
$time_finish=$all_time[$i_stop_finish];

echo»

YOU CAN USE ONE ROUT AND GET YOUR DESTINATION:»;
echo»
Rout $name_rout will be on the start at time: $time_start»;
echo»
And on the destination will be at time: $time_finish»;

$find++;
break;
}
$i_stop_finish++;
} while($i_stop_finish<$numb_stop);
}
}
return $find;
}

А вот вторым шагом мы в объект типа Route, созданный для остановки start передаём такой же объект созданный для остановки finish как параметр функции find_one_change(…), для поиска возможных пересадок с маршрута который останавливается на остановке start, на маршрут, останавливающийся на остановке finish.
function find_one_change($routes_finish) {

$db = mysql_connect(«localhost», «root»);
mysql_select_db(«BUS_STOP»,$db);
$find=0;
$numb_startr=$this->number_routes;
$numb_finishr=$routes_finish->number_routes;
$all_startr=$this->route; // array of objects
$all_finishr=$routes_finish->route; // array of objects
$id_stop_finish=$routes_finish->id_busstop;
$id_stop_start=$this->id_busstop;
for($i=0; $i<$numb_startr; $i++) {
for($j=0; $j<$numb_finishr; $j++) {
$id_strout=$all_startr[$i]->id_route;
$id_fnrout=$all_finishr[$j]->id_route;
$today_finish=$all_finishr[$j]->rout_today;
$today_start=$all_startr[$i]->rout_today;
if($id_strout != $id_fnrout & $today_start == «y» & $today_finish == «y») {
$res= find_able($all_startr[$i], $all_finishr[$j]);
if($res[3] != 0) {
echo»

we can reach destination use bus with change:»;
$name_start=$all_startr[$i]->name_route;
$all_timestart=$all_startr[$i]->rout_times;
$prog_name=$all_startr[$i]->id_route;
$timestart_sit=$all_timestart[$res[0]];
$timestart_chg=$all_timestart[$res[1]];

$sql=»select name»;
$sql=»$sql from common, rt$prog_name»;
$sql=»$sql where curent=’$res[1]’ and stop_name=id»;
if($result = mysql_query($sql,$db)) {
$que=mysql_fetch_row($result);
$que[]=mysql_num_rows($result); //last element for control
}

$name_finish=$all_finishr[$j]->name_route;
$all_timefinish=$all_finishr[$j]->rout_times;
$timefinish_sit=$all_timefinish[$res[2]];
$timefinish_out=$all_timefinish[$res[3]];
echo»
On the start bus-stop sit on the $name_start rout which stop here:»;
echo»
$timestart_sit»;
echo»
name BUS-STOP for change:$que[0]»;
echo»
And Bus $name_start will be here at time:»;
echo»
$timestart_chg»;
echo»
on the Bus-stop $que[0] you have to sit on the»;
echo»
next bus:$name_finish, which will be here at time:»;
echo»
$timefinish_sit»;
echo»
And you get your destination at time:»;
echo»
$timefinish_out»;
$find++;
}
}
}
}
mysql_close();
return $find; // number finded routes
}
}

Для работы этой функции привлекается вспомогательная функция find_able(…) В которую как параметр передаём объект — маршрут отходящий от остановки start и объект — маршрут который останавливантся на остановке finis. Проверям возможность пересадки с первого на второй. При этом для каждого автобуса отходящего от остановки start сканируем по его становкам от остановки посадки и смотрим, а есть ли такая же у автобуса, который останавливается на остановке finish. Если есть, то в возвращаемую переменную $ret ( array ) записываем индексы для этой остановки для первого и для второго $ret[1]=$i; $ret[2]=$j; и потом смотрим, а есть ли у финиширующего автобуса остановка назначения после этой самой остановки пересадки. Если есть — записываем $ret[3]=$j;

Отработав, функция возвращает $ret[] и если 4-й элемент $ret ( $ret[3] ) равен 0, то значит мы не можем пересесть с первого на второй и достичь остановки назначения. Найдя искомую остановку ( то есть ту, на которой останавливаются и тот и другой маршруты ) по её ID из базы данных получим имя, вся остальная информация находиться в объектах и остаётся только выдать её пользователю.

В данном случае не найдено прямого маршрута, то есть на который мы можем сесть на остановке start и добраться до остановки finish, но есть возможность добраться до остановки назначения с пересадкой — указан маршрут на который нужно сесть и строка времён, кагда он останавливается здесь. Указана остановка на которой необходимо сойти для пересадки на другой маршрут и строка времён, когда вы прибудете на неё. Далее такая же информация про маршрут, на который следует пересесть: строка времён, когда он бывает на данной остановке и когда он останавливается на остановке finish. В данном примере, несмотря на то что маршрут 1 останавливается и на остановке start и на остановке finish как возможный он не показан — дело в том, что проходит он их в обратном для нас порядке.

В фолдере create_tables найдёте всё необходдимое. На Linux просто «руками» создайте базу данных BUS_STOP, войдите в фолдер create_tables, файл createTables.sh сделайте исполняемым и запустите его. Все необходимые таблицы в BUS_STOP будут созданы и заполнены. Скрипт createTables.sh использует файлы, находящиеся там же, и если не получается — можно руками, создать таблицы, заглядывая в файл create_all_tables.dump и заполнить их используя файлы common, common_2, routes и rt01, rt02, …, rt34. Пользователям Windows видимо так и придётся… :-( .

После установки базы данных BUS_STOP файлы choice.php3, find.php3 и functions.php3 положить, как обычно, под Apache и запустить choice.php3.

Источник:   codingrus.ru

Вы можете оставить комментарий, или обратную ссылку на Ваш сайт.

Оставить комментарий

Похожие статьи