class blog_template_parse{
private $starting_tag_char='<';
private $endding_tag_char='>';
private $all_box_list=array(
"BlogPostBlock"
);
public function __construct(){
}
private function check_tag_exist($tagname=''){
if(in_array($tagname,$this->all_box_list)){
return 1;
}
return 0;
}
private function starting_character($chars=''){
for($i=0,$s=strlen($chars);$i<$s;$i++){
if(!(ctype_alnum($chars[$i])||$chars[$i]=='_'||$chars[$i]=='='||$chars[$i]=='#')){
return 0;
}
}
return 1;
}
private function cmd_character($chars=''){
$flag=0;
if(!($s=strlen($chars))){
return 0;
}
for($i=0;$i<$s;$i++){
if(!(ctype_alnum($chars[$i])||$chars[$i]=='_'||$chars[$i]=='-')){
return 0;
}
}
return 1;
}
private function variable_protocol($chars=''){
if($s=strlen($chars)){
if(ctype_alpha($chars[0])||$chars[0]=='_')
{
for($i=1;$i<$s;$i++){
if(!(ctype_alnum($chars[$i])||$chars[$i]=='_')){
return 0;
}
}
return 1;
}
}
return 0;
}
private function strip_space($str='',$size=0,$i=0,&$line_count=0){
$line_count=0;
while($i<$size&&ord($str[$i])<=32)
{
if(ord($str[$i])==10)
{
$line_count++;
}
$i++;
}
return $i;
}
private function attribute_parse($i=0,&$line_counter=0,&$res_attrib ute=array()){
$line_counter=0 ;
$str=$this->source_str;
$size=$this->source_str_size;
if(!(ord($str[$i])<=32||$str[$i]==$this->endding_tag_char)){
return $i;
}
$temp_line_counter=0;
$front_attribute_index=$i;
$attributes=array();
$i=$this->strip_space($str,$size,$i,$temp_line_counter);
$line_counter+=$temp_line_counter;
while($i<$size){
if($str[$i]==$this->starting_tag_char){
$res_attribute=$attributes;
return $i;
break;
}elseif($str[$i]=='='&&ord($str[$i])>32){
$attribute_name='';
$e=$i-1;
while($e>=0){
if($e==$front_attribute_index) {
$e++;
break;
}
elseif(ord($str[$e])<=32){
$e++;
if(ord($str[$e])==10)
{
$line_counter++;
}
break;
}
$e--;
}
$i++;
$attribute_name=substr($str,$e,$i-$e-1);
if(!trim($attribute_name)){continue;}
$attribute_value='';
$i=$this->strip_space($str,$size,$i,$temp_line_counter);
$line_counter+=$temp_line_counter;
if($str[$i]=="'"){
$i++;
while($i<$size){
if($str[$i]=="'")
{
$front_attribute_index=$i;
break;
}
else
{
if(ord($str[$i])==10)
{
$line_counter++;
}
$attribute_value.=$str[$i];
}
$i++;
}
}elseif($str[$i]=='"'){
$i++;
while($i<$size){
if($str[$i]=='"'){
$front_attribute_index=$i;
break;
}else
{
if(ord($str[$i])==10)
{
$line_counter++;
}
$attribute_value.=$str[$i];
}
$i++;
}
}else{
while($i<$size){
if(ord($str[$i])<=32) {
if(!isset($attributes[strtolower($attribute_name)])){
$attributes[strtolower($attribute_name)]=$attribute_value;
}
if(ord($str[$i])==10)
{
$line_counter++;
}
$front_attribute_index=$i;
break;
}elseif($str[$i]==$this->endding_tag_char){
if(!isset($attributes[strtolower($attribute_name)])){
$attributes[strtolower($attribute_name)]=$attribute_value;
}
$res_attribute=$attributes;
return $i;
}
$attribute_value.=$str[$i];
$i++;
}
}
if(!isset($attributes[strtolower($attribute_name)])){
$attributes[strtolower($attribute_name)]=$attribute_value;
}
}
$i++;
}
return $i;
}
public function literally_parse($source='',&$str_res='',&$error_st r=''){
$error_str='';
$str=$this->source_str=$source;
$size=$this->source_str_size=strlen($source);
$res=array();
$stack=array();
$temp_str='';
$col=0;
$row=1;
$arr_loop_continue_stack=array();
$i=0;
$temp_line_counter=0;
while($i<$size){
if($i+1<$size && $str[$i]==$this->starting_tag_char && $this->starting_character($str[$i+1])){
if(strlen($temp_str)){
$res[]=array('t'=>'text','v'=>$temp_str);
$temp_str='';
}
$succes_box='';
$data_list=array();
$start_element=$i;
$endding_element_index=0;
$i++;
$temp_cmd_name='';
$end_element=0;
// $equal_sign=0;
// $var_exist=0;
// $block_or_loop_exist=0;
// $var_list=array();
// $block_content_error=0;
$cmd_parameter=array();
$cmd_parameter=array();
// $special_block=0;
$data_exist=0;
$char_is_space=0;
$char_is_colon=0;
$char_is_dot=0;
while($i<$size){
//if(!$this->starting_character($str[$i])){
// break;
// }
if(ord($str[$i])<=32||$str[$i]==$this->endding_tag_char)
{
if(ord($str[$i])<=32){
$char_is_space=1;
}
if(!$data_exist)
{
if(strlen($temp_cmd_name))
{
if($this->check_tag_exist($temp_cmd_name))
{
$succes_box=strtolower($temp_cmd_name);
if($char_is_space)
{
$i=$this->attribute_parse($i,$temp_line_counter,$attribute_ res);
$row+=$temp_line_counter;
$cmd_parameter=$attribute_res;
}
}
else
{
break;
}
}else{
if($char_is_space)
{
$i=$this->attribute_parse($i,$temp_line_counter,$attribute_ res);
$row+=$temp_line_counter;
$cmd_parameter=$attribute_res;
}
}
}else
{
if(strlen($temp_cmd_name))
{
$data_list[]=strtolower($temp_cmd_name);
if($char_is_space)
{
$i=$this->attribute_parse($i,$temp_line_counter,$attribute_ res);
$row+=$temp_line_counter;
$cmd_parameter=$attribute_res;
}
}
else
{
break;
}
}
if($i<$size&&$str[$i]==$this->endding_tag_char )
{
$end_element=1;
$endding_element_index=$i;
break;
}else{
break;
}
}
elseif($i<$size){
if(!$this->cmd_character($str[$i])){
break;
}
$temp_cmd_name.=$str[$i];
}
$i++;
}//end while
// var_dump('start box',$succes_box);exit;
// exit;
if($end_element)
{
if(strlen($succes_box))
{ //parsing block
if(empty($cmd_parameter))
{
$res[]=array('t'=>'start','v'=>$succes_box);
}else
{
$res[]=array('t'=>'start','v'=>($succes_box),'p'=>$cmd_p arameter);
}
$stack=$succes_box;
//$temp_str.=substr($str,$start_element,$i-$start_element+1);
}else
{
$temp_str.=substr($str,$start_element,$i-$start_element+1);
}
}
else{
//error in syntax
/*
if(@$str[$i]==$this->starting_tag_char){ //starting new tag
$temp_str.=substr($str,$start_element,$i-$start_element);
continue;
}else
*/
{
// var_dump('else');
$temp_str.=substr($str,$start_element,$i-$start_element+1);
}
}
}
elseif($i+2<$size&&$str[$i]==$this->starting_tag_char&&$str[$i+1]=='/'&&$this->starting_character($str[$i+2])){
$start_element=$i;
$i+=2;
if(strlen($temp_str)){
$res[]=array('t'=>'text','v'=>$temp_str);
$temp_str='';
}
$succes_box='';
$endding_element_index=0;
$temp_cmd_name='';
$end_element=0;
$char_is_space=0;
$char_is_colon=0;
$char_is_dot=0;
while($i<$size){
//if(!$this->starting_character($str[$i])){
// break;
// }
if(ord($str[$i])<=32||$str[$i]==$this->endding_tag_char)
{
if(ord($str[$i])<=32){
$char_is_space=1;
}
if(strlen($temp_cmd_name))
{
if($this->check_tag_exist($temp_cmd_name))
{
$succes_box=strtolower($temp_cmd_name);
if($char_is_space)
{
$i=$this->attribute_parse($i,$temp_line_counter,$attribute_ res);
$row+=$temp_line_counter;
$cmd_parameter=$attribute_res;
}
}
else
{
break;
}
}else{
if($char_is_space)
{
$i=$this->attribute_parse($i,$temp_line_counter,$attribute_ res);
$row+=$temp_line_counter;
$cmd_parameter=$attribute_res;
}
}
if($i<$size&&$str[$i]==$this->endding_tag_char )
{
$end_element=1;
$endding_element_index=$i;
break;
}else{
break;
}
}
elseif($i<$size){
if(!$this->cmd_character($str[$i])){
break;
}
$temp_cmd_name.=$str[$i];
}
$i++;
}//end while
if($end_element&&strlen($succes_box))
{
if(empty($stack))
{
$temp_str.=substr($str,$start_element,$i-$start_element+1);
break;
//$error=('synatx error : endding tag without staring tag.') ; return 0;
}
/*
$pop=array_pop($stack);
if($pop!=$succes_box){
$implode_start=implode(':',$pop);
$implode_end=implode(':',$succes_box);
$error_str='synatx error : starting with {'.$implode_start.'} but endding with {/'.$implode_end.'} on line '.$row.' .';
return 0;
}
*/
$res[]=array('t'=>'end','v'=>$succes_box);
}
else
{
$temp_str.=substr($str,$start_element,$i-$start_element+1);
}
}
else{
$temp_str.=$str[$i];
if(ord($str[$i])==10){
$row++;
}
}
$i++;
}
// if(!empty($error))
// {
// return 0;
// }
if(strlen($temp_str))
{
$res[]=array('t'=>'text','v'=>$temp_str);
}
/*
if(!empty($stack))
{
while(!empty($stack))
{
$pop=array_pop($stack);
$res[]=array('t'=>'end','v'=>($pop));
}
}
*/
$str_res=serialize($res);
return 1;
}
}
$blog_template_parse=new blog_template_parse();
$template="<BlogPostBlock id=55>this string</BlogPostBlock>";
$blog_template_parse->literally_parse($template,$str_res,$blog_template _error);
if(strlen($blog_template_error))
{
die($blog_template_error) ;
}
$arr=unserialize($str_res);
var_dump($arr);
خروجی
array
0 =>
array
't' => string 'start' (length=5)
'v' => string 'blogpostblock' (length=13)
'p' =>
array
'id' => string '55' (length=2)
1 =>
array
't' => string 'text' (length=4)
'v' => string 'this string' (length=11)
2 =>
array
't' => string 'end' (length=3)
'v' => string 'blogpostblock' (length=13)