Знаю что нагуглить можно, просто хочется проверенные (самому писать совсем некогда)... Может кто пользовался или сам написал и не жалко?! Буду очень признателен. Главное чтобы комментарии были древовидными, т.е. можно было оставить комментарий на комментарий, и так любой глубины. На голосовалку вообще пилевать.. Главное чтобы голосовала, а что надо подправлю
держи, писал с ходу... PHP: <? class voter { public $ident; static $data; function __construct($ident) { $this->ident=$ident; } function GetVoteArr() { $data=self::GetSerial('votedata'); $res=array(); if ($data[$this->ident]) { $res['tema']=$data[$this->ident]['tema']; $allbals=$this->GetAllBals($data[$this->ident]); for($i=0,$c=count($data[$this->ident])-1,$row=$data[$this->ident];$i<$c;$i++) { $res['vars'][$i]['bals']=$row[$i]['bals']; $res['vars'][$i]['name']=$row[$i]['name']; $res['vars'][$i]['id_var']=$i; if ($row[$i]['bals']) $res['vars'][$i]['procent']=round($row[$i]['bals']/$allbals*100); else $res['vars'][$i]['procent']=0; } return $res; } return false; } function addbal($id_var) { $data=self::GetSerial('votedata'); $ips=self::GetSerial("badips"); $data[$this->ident][$id_var]['bals']++; $ips[]=md5($_SERVER['REMOTE_ADDR']); self::SetSerial($data,'votedata'); self::SetSerial($ips,'badips'); } function hevoted() { $data=self::GetSerial("badips"); if (@in_array(md5($_SERVER['REMOTE_ADDR']),$data)) { return true; } return false; } private function GetAllBals($data) { $GLOBALS['allbals']=0; array_walk($data,create_function('$val,$key','$GLOBALS[\'allbals\']+=$val[\'bals\'];')); return $GLOBALS['allbals']; } static function setVote($ident,$tema,$vars) { $arr=self::GetSerial('votedata'); $arr[$ident]['tema']=htmlspecialchars($tema); for($i=0,$c=count($vars);$i<$c;$i++) { $arr[$ident][$i]['name']=htmlspecialchars($vars[$i]); $arr[$ident][$i]['bals']=0; } self::SetSerial($arr,'votedata'); } static function GetSerial($name) { if(!self::$data[$name]){ $fp=@file_get_contents("$name.php"); $fp=str_replace("<?die();?>","",$fp); self::$data[$name]=unserialize($fp); } return self::$data[$name]; } static function SetSerial($arr,$name) { $arr="<?die();?>".serialize($arr); if (file_exists("$name.php")) unlink("$name.php"); file_put_contents("$name.php",$arr); } } ?> вроде должно работать =))
замени ещё PHP: $res['vars'][$i]['procent']=round($allbals/$row[$i]['bals']*100); на PHP: $res['vars'][$i]['procent']=round($row[$i]['bals']/$allbals*100); это PHP: private function GetAllBals($data) { $res=0; $res+=array_walk($data,create_function('$val,$key','return $val[\'bals\'];')); return $res; } на PHP: private function GetAllBals($data) { $GLOBALS['allbals']=0; array_walk($data,create_function('$val,$key','$GLOBALS[\'allbals\']+=$val[\'bals\'];')); return $GLOBALS['allbals']; } // короче, я уже заменил =)
пример использования PHP: <? if (!file_exists("votedata.php")) voter::setVote("id","The Thema",array("Ответ 1","Ответ 2","Ответ 3")); $v=new voter("id"); $arr=$v->GetVoteArr(); if(!$v->hevoted()) { if (isset($_POST['otv'])) { $v->addbal($_POST['otv']); header("refresh:0;"); } print $arr['tema']."<br><form method=POST>"; for($i=0,$c=count($arr['vars']);$i<$c;$i++) { print "<input type=radio value='{$arr['vars'][$i]['id_var']}' name='otv'> {$arr['vars'][$i]['name']}<br>"; } print "<input type=submit></form>"; }else { print $arr['tema']."<br>"; for($i=0,$c=count($arr['vars']);$i<$c;$i++) { print "{$arr['vars'][$i]['name']}({$arr['vars'][$i]['bals']}) - {$arr['vars'][$i]['procent']}%<br>"; } } ?>
md5, я думаю это было просто легкой иронией над UPD: Чем-то мне мою первую гостевую напоминает... UPD UPD: И еще некоторые более поздние работы уровня : ибать нужно до 19 успеть!!!!
главное работает! =)) хотя впринципе, будет нормально, если добавить пяток проверок, и итоговый массив запихивать в св-ва по типу данных потому что такой массив это не гуд Код (Text): $res['vars'][$i]['procent'] фигасе, у тебя первая гостевая ООП была 0_о Таг, кто будет писать комментарии? :twisted:
Mr.M.I.T., я в PHP после краткого знакомства с Java SE пришел, на чем же еще могла быть моя первая гостевая?
ну тогда, древовидные комментарии на скорую руку, с постаничным выводом не уверен PHP: <? $cnf=array(); $cnf['db_name']=''; $cnf['db_user']=''; $cnf['db_encode']='cp1251'; $cnf['db_pass']=''; $cnf['db_host']='localhost'; $cnf['table_name']='comments'; $cnf['db_pref']='pref'; $cnf['page_num']=10; $cnf['page_block']=5; $cnf['data_format']='d.m.Y H:i'; class db { public $link,$pref,$cnf,$numrows,$afectrows; function __construct($cnf) { $this->link = mysql_connect($cnf['db_host'],$cnf['db_user'],$cnf['db_pass']) or die(mysql_error()); if ($cnf['db_encode']) mysql_query('SET NAMES '.$cnf['db_encode']); mysql_select_db($cnf['db_name'],$this->link); $this->pref=$cnf['db_pref']; $this->cnf=$cnf; } function query($sql) { $sql=str_replace(array("?p","?P"),$this->pref,$sql); $sql=mysql_query($sql); $this->numrows=@mysql_num_rows($sql); return $sql; } function fetch_array($res) { return mysql_fetch_assoc($res); } function super_query($sql) { $res=array(); $sql=$this->query($sql); if ($this->numrows) { while($row=$this->fetch_array($sql)) { $res[]=$row; } } return $res; } function result_query($sql) { $sql=$this->query($sql); return @mysql_result($sql,0); } function SqlGetNumRows($table,$where=1) { return $this->result_query("SELECT COUNT(*) FROM `?p_$table` WHERE $where"); } function SqlGetRow($table,$row,$where=1) { return $this->result_query("SELECT `$row` FROM `?p_$table` WHERE $where LIMIT 1"); } function SqlGetRows($table,$row,$where=1) { return $this->super_query("SELECT `$row` FROM `?p_$table` WHERE $where"); } function SqlGetLines($table,$where) { return $this->super_query("SELECT * FROM `?p_$table` WHERE $where"); } function SqlGetLine($table,$where) { return $this->fetch_array($this->query("SELECT * FROM `?p_$table` WHERE $where LIMIT 1")); } function table_exists($name) { if (!file_exists("isinst.file")) { $res=mysql_list_tables($this->cnf['db_name']); while($row=mysql_fetch_row($res)) { if ($row[0]==$this->pref."_".$name){ fopen("isinst.file","w"); return true; } } return false; } return true; } function insert($table,$value) { $ident=false; if (!is_array($table) && is_array($value[0])) { $values=''; for($i=0,$c=count($value);$i<$c;$i++) { $values.="("; $in=''; foreach($value[$i] as $key=>$val) { if (is_string($key)) $in.="`$key`,"; $values.="'".mysql_real_escape_string($val)."',"; } $values=substr($values,0,-1); $values.="),"; if ($in) $in="(".substr($in,0,-1).")"; } $values=substr($values,0,-1); $ident=$this->query("INSERT INTO `".$this->pref."_".$table."` ".$in." VALUES ".$values); }else if (!is_array($table) && is_array($value)) { $values='';$in=''; foreach($value as $key=>$val) { $values.="'".mysql_real_escape_string($val)."',"; if (is_string($key)) $in.="`$key`,"; } $values=substr($values,0,-1); $values="($values)"; if ($in) $in="(".substr($in,0,-1).")"; $ident=$this->query("INSERT INTO `".$this->pref."_".$table."` ".$in." VALUES ".$values); }else if(!is_array($table) && !is_array($value)) { $ident=$this->query("INSERT INTO `".$this->pref."_".$table."` VALUES ($value)"); } $this->afectrows=mysql_affected_rows(); return $ident; } function update($table,$value,$where=1) { $ident=false; if(!is_array($value[0])) { if(is_array($where)) trigger_error("Ошибка: 3 параметр метода `update` в данном случае не может быть массивом",E_USER_ERROR); $set=''; foreach($value as $key=>$val) { $set.="`$key`='".mysql_real_escape_string($val)."',"; } $set=substr($set,0,-1); $ident=$this->query("UPDATE ".$this->pref."_".$table." SET ".$set." WHERE $where"); $this->afectrows=mysql_affected_rows(); }else { $this->afectrows=0; for($i=0,$c=count($value);$i<$c;$i++) { $set='';$wh=1; foreach($value[$i] as $key=>$val) { $set.="`$key`='".mysql_real_escape_string($val)."',"; } if (is_array($where)) $wh=$where[$i]; else $wh=$where; $ident=true; if(!$this->query("UPDATE ".$this->pref."_".$table." SET ".$set." WHERE $wh")) { $ident=false; break; } $this->afectrows+=mysql_affected_rows(); } } return $ident; } function del($table,$value) { $ident=false; if (!is_array($table) && !is_array($value)) { $ident=$this->query("DELETE FROM ".$this->pref."_".$table." WHERE ".$value); }else if (!is_array($table) && is_array($value)) { $sql="DELETE FROM ".$this->pref."_".$table." WHERE "; for($i=0,$c=count($value);$i<$c;$i++) { $sql.=$value[$i].($i!==$c-1?" OR ":""); } } $this->afectrows=mysql_affected_rows(); return $ident; } static function escape($var) { return mysql_real_escape_string($var); } } class comments { public $db,$cnf,$error; public $post=array(); public $vars=array(); function __construct() { global $cnf; $this->cnf=$cnf; $this->db=new db($cnf); $this->init(); } private function install() { $this->db->query(" CREATE TABLE `{$this->cnf['db_pref']}_{$this->cnf['table_name']}` ( `id` int(11) NOT NULL auto_increment, `parent` varchar(300) NOT NULL, `name` tinytext NOT NULL, `text` text NOT NULL, `data` varchar(100) NOT NULL, PRIMARY KEY (`id`), KEY `parent` (`parent`) ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1; ") or die(mysql_error()); } private function init() { if(!$this->db->table_exists($this->cnf['table_name'])) { $this->install(); header("Refresh:2"); $this->error("Установка..."); }else { $this->controller(); } } private function error($error) { $this->error.="<div class='error'>$error</div>"; } private function controller() { if (!$this->userReq()){ $this->post=$this->GetPost(); $this->vars['page']=$this->GetPage(); $this->vars['form']=$this->GetForm(); } } private function GetNPage() { $n=(db::escape($_GET['n'])-1)*$this->cnf['page_num']; if ($n<0)$n=0; return $n; } private function GetNRealPage() { $n=db::escape($_GET['n']); if (!$n) $n=0; return $n; } private function GetPage() { return support::Pager($this->cnf['page_num'],$this->cnf['page_block'], $this->GetNRealPage(),"{$_SERVER['PHP_SELF']}?n={i}",$this->SqlGetNumComRows() ); } private function GetForm() { return " <script laguage='javascript'> function setParent(par) { document.getElementById('parent').value=par; window.location='#form'; } </script> <form method=POST> <a name='form'></a> <table width=100% border=1> <tr> <td>Name</td><td><input type=text name='name'></td> <tr> <td>Text</td><td><textarea name='text' cols=50 rows=8></textarea></td> <tr> <td colspan=2><input type=submit></td> </table> <input type=hidden name='parent' value='0' id='parent'> </form> "; } private function GetPost() { $sql=$this->SqlGetComList(); if ($this->db->numrows) { return $this->Formatter($sql); }else { $this->error("Ошибка: Нет не одного сообщения"); } return array(); } private function Formatter($sql) { $res=array(); while($row=$this->db->fetch_array($sql)) { $row['data']=date($this->cnf['data_format'],$row['data']); $row['board']=$this->GenBoard($row['parent']); $row['text']=nl2br($row['text']); $res[]=$row; } return $res; } private function GenBoard($p) { return count(explode("-",$p))-1; } private function SqlGetComList() { return $this->db->query(" SELECT * FROM ?p_comments ORDER BY `parent` LIMIT ".$this->GetNPage().",".$this->cnf['page_num']." "); } private function SqlGetNumComRows() { return $this->db->SqlGetNumRows($this->cnf['table_name']); } private function userReq() { if (support::issetpost("name,text")) { if(!support::emptypost("name,text")) { $this->AddAction(); return true; }else { $this->error("Ошибка: Обязательные поля нужно заполнить"); } } return false; } private function AddAction() { $res=support::Walker($_POST,array("func"=>"htmlspecialchars","keys"=>array("text","name"))); if (!$_POST['parent'] || !is_numeric($_POST['parent'])) $parent=0; else $parent=db::escape($_POST['parent']); $parentres=$this->db->SqlGetRow($this->cnf['table_name'],"parent","id='".db::escape($parent)."'"); if ($parentres) { $parentrow=$this->db->SqlGetNumRows($this->cnf['table_name'],"parent LIKE ('$parentres%')")-1; $parentres.="-".($parentrow+1); }else { $parentrow=$this->db->SqlGetNumRows($this->cnf['table_name'],"parent NOT LIKE ('%-%')"); $parentres=$parentrow+1; } if ($this->db->insert($this->cnf['table_name'], array( "id"=>"NULL", "name"=>$res['name'], "text"=>$res['text'], "parent"=>$parentres, "data"=>time(), ))) { $this->error("Сообщение добавлено"); header("Refresh:1"); }else { $this->error("Ошибка при добавлении сообщения"); header("Refresh:2"); } } } class support { static function emptypost($p) { $p=explode(",",$p); for($i=0,$c=count($p);$i<$c;$i++) { if (empty($_POST[$p[$i]])) { return true; } } return false; } static function issetpost($p) { $p=explode(",",$p); for($i=0,$c=count($p);$i<$c;$i++) { if (!isset($_POST[$p[$i]])) { return false; } } return true; } static function Walker($arr,$opt) { $fcc=' if(!$opt[\'keys\']) $opt[\'keys\']=array(); if (in_array($key,$opt[\'keys\']) || empty($opt[\'keys\'])) { $val=$opt[\'func\']($val); }'; array_walk($arr,create_function('&$val,$key,$opt',$fcc),$opt); return $arr; } static function Pager($page_num,$page_block,$n,$tpl,$all) { if($n<=0)$n=1; $max=ceil($all/$page_num); if ($max<=0) $max=1; $ot=$n-2; if ($ot<=0) $ot=1; $po=$ot+$page_block-1; if ($po>$max) $po=$max; $page=''; if ($po==$max) $ot=$po+1-$page_block; if ($ot<=0) $ot=1; if ($ot==2) $page.='...'; if ($ot>2) { $page.="<a href='".str_replace('{i}','1',$tpl)."'>[1]</a>"; if ($ot>3) $page.="<a href='".str_replace('{i}','2',$tpl)."'>[2]</a>"; $page.='...'; } for($i=$ot;$i<=$po;$i++) { if ($n==$i) { $page.="<b>[$i]</b>"; }else { $page.="<a href='".str_replace('{i}',$i,$tpl)."'>[$i]</a>"; } } if ($po<=$max-2){ $page.='...'; if ($po<$max-2) $page.="<a href='".str_replace('{i}',($max-1),$tpl)."'>[".($max-1)."]</a>"; $page.="<a href='".str_replace('{i}',$max,$tpl)."'>[$max]</a>"; } if ($po==$max-1) $page.='...'; return $page; } } $com=new comments(); print " <style> .error { border:1px solid red; } </style> "; if ($com->error) print $com->error."<br>"; for($i=0,$c=count($com->post),$row=$com->post;$i<$c;$i++) { $margin=$row[$i]['board']*20; print " <table width=100% border=1 style='margin-left:".$margin."px'> <tr> <td>{$row[$i]['name']} - {$row[$i]['data']}</td> <tr> <td>{$row[$i]['text']}<br><a href='javascript://' onclick=\"setParent('{$row[$i]['id']}');\">Ответить</a></td> </table> "; } print "<br>Str:".$com->vars['page']."<br>".$com->vars['form']; ?>
Mr.M.I.T. постраничный вывод и не нужен... ты все с нуля прям так и написал??? тебе нечем заняться?? ) спасибо конечно, но тебе никто не говорил, что ты монстер
Kreker ну за 40 =) а что? ведь одно дело писать то что никогда не писал, в другое - писать одно и тоже сто первый раз... у меня тут времени больше ушло на планирование структуры дерева...
а можно поинтересоваться почему так реализовано дерево?? почему чисто ид в поле парент не захотел хранить?
ShamahN имеешь ввиду рекурсию? тогда будет куча запросов, или как-то кешировать нужно... а если имеешь ввиду хранить иды через тире, тогда order by работать не будет, дерево сложно выводить...
угу угу, тебе кстати придётся ещё изменить таблицу, сделать привязку к публкациям =) а то я забыл что-то 0о...
Mr.M.I.T. думаю в паренте добавить перед твоим парентом что-нить типа "idstat&" или поле добавить... по-моему одно и то же... кста, а класс bd этот ж скорее всего заготовка у тебя какая-нить? или ты его каждый раз заново ваяешь? Я к чему спрашиваю. Просто никогда не пользовался классами для БД (может и не стоит), а тут решил попробовать... думаешь самому накатать или взять какой-нить dbsimple?