function str_cut($html,$max_length=100,$ender=false,$cut_to_word=false)
{
$isUtf8 = true;
$space_ended = true;
$result_length = 0;
$position = 0;
$add_ender = false;
$tags = array();
$output = '';
$re = $isUtf8 ? '{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;|[\x80-\xFF][\x80-\xBF]*}' : '{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;}';
while($result_length < $max_length && preg_match($re, $html, $match, PREG_OFFSET_CAPTURE, $position))
{
list($tag, $tag_position) = $match[0];
$str = substr($html, $position, $tag_position - $position);
if ($result_length + strlen($str) > $max_length)
{
$output .= substr($str, 0, $max_length - $result_length);
$result_length = $max_length;
break;
}
$output .= $str;
$result_length += strlen($str);
if($result_length >= $max_length)
{
break;
}
if($tag[0] == '&' || ord($tag) >= 0x80)
{
$output .= $tag;
$result_length++;
}
else
{
$tagName = $match[1][0];
if($tag[1] == '/')
{
$openingTag = array_pop($tags);
assert($openingTag == $tagName);
$output .= $tag;
}
elseif($tag[strlen($tag) - 2] == '/')
{
$output .= $tag;
}
else
{
$output .= $tag;
$tags[] = $tagName;
}
}
$position = $tag_position + strlen($tag);
}
if($result_length < $max_length && $position < strlen($html))
{
$output .= substr($html, $position, $max_length - $result_length);
}
if($result_length == $max_length && $position < strlen($html))
{
$add_ender = true;
}
if($cut_to_word)
{
$next_char = substr($html, $position+1,1);
if(!preg_match('/\s/', $next_char))
{
$space_ended = false;
}
if(!$space_ended)
{
if(!empty($tags))
{
$space_pos = strrpos($output,' ');
if($space_pos > 0)
{
$output = substr($output,0,$space_pos);
}
}
else
{
$space_pos = strrpos($output,'<');
$space_pos = strrpos($output,' ',$space_pos);
if($space_pos > 0)
{
$output = substr($output,0,$space_pos);
}
}
}
}
if($ender and $add_ender)
{
$output = $output.(string)$ender;
}
while(!empty($tags))
{
$output .= '</'.array_pop($tags).'>';
}
return $output;
}