📄 functions.php
字号:
<?phperror_reporting(E_ALL & ~E_NOTICE);@set_time_limit(0);// ############################################################################// A version of array_contains() that uses binary sort to find the element// Only use on sorted arrays!!!function array_contains_binary($needle, &$haystack) { if (!is_array($haystack)) { return false; } $low = 0; $high = count($haystack); $needle = strtolower($needle); while ($low <= $high) { $mid = floor(($low + $high) / 2); if (strcasecmp($needle, $haystack[$mid]) == 0 ) { return true; break; } elseif (strcasecmp($needle, $haystack[$mid]) < 0 ) { $high = $mid - 1; } else { $low = $mid + 1; } } return false;}// ############################################################################// A version of in_array() that allows case-insensitive matching (by default!)function array_contains($needle, $haystack, $strict = false, $matchcase = false) { if (!is_array($haystack)) { return false; } if (!$matchcase and is_string($needle)) { $needle = strtolower($needle); } foreach ($haystack as $element) { if (!$matchcase and is_string($needle)) { $element = strtolower($element); } if (($strict and $needle === $element) or (!$strict and $needle == $element)) { return true; } } return false;}// ############################################################################// Returns $true if $eval is true, $false if it is falsefunction iif($eval, $true, $false = '') { return (($eval == true) ? ($true) : ($false));}// ############################################################################ // function readfromfile($filename, $binary = true, $getdata = true) { $mode = 'r'.iif($binary, 'b'); $data = ''; if (is_readable($filename) and is_resource($fp = @fopen($filename, $mode)) and (!$getdata or filesize($filename) == 0 or $data = @fread($fp, @filesize($filename))) and @fclose($fp)) { return $data; } else { return false; } }// ############################################################################ // Calculates microtime difference from $start function microdiff($start) { return realmicrotime() - realmicrotime($start); } // ############################################################################ // Returns a real timestamp from a microtime function realmicrotime($time = null) { if ($time === null) { $time = microtime(); } $timebits = explode(' ', $time); return $timebits[0] + $timebits[1]; }// ############################################################################// Calculates the LCS between the two strings and return the number of similar charsfunction spell_similar($A, $B) { $L = array(); $m = strlen($A); $n = strlen($B); for ($i = $m; $i >= 0; $i--) { for ($j = $n; $j >= 0; $j--) { if ($i >= $m or $j >= $n) { $L[$i][$j] = 0; } elseif ($A[$i] == $B[$j]) { $L[$i][$j] = 1 + $L[$i+1][$j+1]; } else { $L[$i][$j] = max($L[$i+1][$j], $L[$i][$j+1]); } } } return $L[0][0] / max($m, $n);}// ############################################################################// Processes input for fieldsfunction spell_process($text, $method, $useHtml, $sendAfter) { global $_meta_markers; $starttime = microdiff(STARTTIME); $intMaxSuggestions = 6; $showback = 6; $showforward = 6; $userDictionaryAvailable = false; $userWords = $realWords = $misspelledArray = $deadKeys = $tagKeys = $wordKeys = $sxValues = array(); $jsOutput = ''; //echo '<!-- '; if (!empty($text)) { // Operate on the HTML text so it's split correctly $strDictArray = preg_split("#\r?\n#", readfromfile('./dict-large.txt')); echo "Words: ".(microdiff(STARTTIME) - $starttime)."<br />"; $strDictArray = array_flip($strDictArray); echo "Flip: ".(microdiff(STARTTIME) - $starttime)."<br />"; $originalString = preg_replace("#\r?\n#", "\n", $text); $words = preg_split('#([^a-z\'])#i', $originalString, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); echo "Split: ".(microdiff(STARTTIME) - $starttime)."<br />"; $tagOpen = false; $realKey = $demoKey = 0; if ($useHtml) { while (list($key, $value) = each($words)) { if ($value == '<') { $tagOpen = true; } elseif ($value == '>' or $tagOpen) { $demoKey--; $words[$demoKey] .= array_extract($words, $key); $deadKeys[] = $key; if ($value == '>') { $tagKeys[] = $realKey; $realKey++; $demoKey = $key; $tagOpen = false; } } else { $realWords[$realKey] = $value; $realKey++; } $demoKey++; } } else { $realWords = $words; } $words = array_values($words);; $wordCount = count($words); //print_R($realWords); echo "HTML: ".(microdiff(STARTTIME) - $starttime)."<br />"; // Tracks original index of word in $words array $oi = 0; // Get user's dictionary /* $getUserWords = $DB_site->query(" SELECT word FROM hive_word WHERE userid = $hiveuser[userid] "); while ($userWord = $DB_site->fetch_array($getUserWords)) { $userWords[] = $userWord['word']; } echo "User: ".(microdiff(STARTTIME) - $starttime)."<br />"; */ // Loop over each word in string $checks = 0; foreach ($realWords as $strWordKey => $strWordIn) { //if (in_array($strWordKey, $tagKeys)) { // This is an HTML tag or a word that was already checked this word // Increment original index and move along //continue; //} $oi = $strWordKey; // Remove invalid characters from the word $strWordOut = $strWordIn; $strWordOut = preg_replace('#[^a-z\']#i', '', $strWordOut); if (substr_count($strWordOut, "'") > 1) { $strWordOut = str_replace("'", '', $strWordOut); } // Remove 's at the end of the word if (substr($strWordOut, -2) == "'s") { $strWordOut = substr($strWordOut, 0, strlen($strWordOut) - 2); } $strWordOut = trim($strWordOut, "' \t\n\r\0\x0B"); // Nothing left... if (empty($strWordOut)) { continue; } // Store the word's key $wordKeys[] = $oi; // Word need not have capitals $checkWord = strtolower($strWordOut); // Search main dictionary $spellOk = isset($strDictArray["$checkWord"]); // Check user's dictionary // I decided to not do this here, but instead check later if // if the any of the suggestions match the actual word which // means it's a word that the user added. The cost of running // this binary search for every word is just not worth it. if (false and !$spellOk and !empty($userWords)) { // Binary sort to find word in user's array // (Only if the array isn't short) if (false and count($userWords) < 20) { $spellOk = in_array($checkWord, $userWords); } else { $low = 0; $high = count($userWords); while ($low <= $high) { $mid = floor(($low + $high) / 2); if (strcasecmp($checkWord, $userWords[$mid]) == 0 ) { $spellOk = true; break; } elseif (strcasecmp($checkWord, $userWords[$mid]) < 0 ) { $high = $mid - 1; } else { $low = $mid + 1; } } } } // If word is spelled wrong, store in array if (!$spellOk) { // Calculate soundex/metaphone using PHP and create the misspelled array entry $sndx = $method($strWordOut); if (!array_contains($sndx, $sxValues)) { $sxValues[] = $sndx; } $misspelledArray[] = array( 'word' => $strWordIn, 'sndx' => $sndx, 'possugs' => array(), 'realsugs' => array(), 'oi' => $oi, ); } } $lastOi = $oi; echo "Spell: ".(microdiff(STARTTIME) - $starttime)."<br />"; $wordKeysFlipped = array_flip($wordKeys); echo "Flip: ".(microdiff(STARTTIME) - $starttime)."<br />"; // Total count of misspelled words in the array $misspelledWordCount = count($misspelledArray); if ($misspelledWordCount > 0) { // Execute query $strSuggArray = preg_split("#\r?\n#", readfromfile('./dict-metaphone-sort.txt')); echo "Suggest: ".(microdiff(STARTTIME) - $starttime)."<br />"; // JavaScript variables that will store all information $jsOutput .= "var msWc = $misspelledWordCount;\n"; $jsOutput .= "var msMissWordAr = new Array($misspelledWordCount);\n"; $jsOutput .= "var msOrigWordAr = new Array($wordCount);\n"; $jsOutput .= "var lastOrigWord;\n"; // Loop over array to get suggestions $doneSugsFor = array(); for ($x = 0; $x < $misspelledWordCount; $x++) { $subAr3 = &$misspelledArray[$x]; $intWordLen = strlen($subAr3['word']); $subArPoss3 = &$subAr3['possugs']; // Create context string $oi = $subAr3['oi']; $oiStart = $wordKeys[(($wordKeysFlipped[$oi] - $showback) >= 0) ? ($wordKeysFlipped[$oi] - $showback) : 0]; $oiEnd = $wordKeys[(($wordKeysFlipped[$oi] + $showforward + 1) <= count($wordKeys) - 1) ? ($wordKeysFlipped[$oi] + $showforward + 1) : count($wordKeys) - 1]; $context = ''; if ($oi > $showback) { $context .= '...'; } for (; $oiStart != $oiEnd + 1; $oiStart++) { if ($oiStart == $oi) { $context .= '<font color="red"><b>'.$words[$oi].'</b></font>'; } else { $context .= $words[$oiStart]; } } if ($oi < ($wordCount - 1 - $showforward)) { $context .= '...'; } // Loop over similarities (possible suggestions), score and get top (real) suggestions // Check if we already did suggestions for this word and if so, load that $dblSimilarityArray = array(); if (false and isset($doneSugsFor["$subAr3[word]"])) { $dblSimilarityArray = $misspelledArray[$doneSugsFor["$subAr3[word]"]]['possugs']; } else { // Binary sort to find word in dict array $low = $_meta_markers[substr($subAr3['sndx'], 0, 3)][0] - 1; $high = $_meta_markers[substr($subAr3['sndx'], 0, 3)][1] + 3; $foundSndx = false; //echo "Low: $low; High: $high;<br />"; while ($low <= $high) { $mid = floor(($low + $high) / 2); $checks++; //$check = strcasecmp($subAr3['sndx'].'|', substr($strSuggArray[$mid], 0, strlen($subAr3['sndx']) + 1)); $check = strcasecmp($subAr3['sndx'], preg_replace('#^([^|]+)\|.*$#', '$1', $strSuggArray[$mid])); if ($check == 0) { $foundSndx = true; break; } elseif ($check < 0) { $high = $mid - 1; } else { $low = $mid + 1; } } if ($foundSndx) { $subArPoss3 = explode('|', substr($strSuggArray[$mid], strlen($subAr3['sndx']) + 1)); } else { $subArPoss3 = array(); } $subCount = count($subArPoss3); if ($subCount <= 1) { $dblSimilarityArray = $subArPoss3; } else { for ($y = 0; $y < $subCount; $y++) { $strSimilarWord = $subArPoss3[$y]; $intSimilarWordLen = strlen($strSimilarWord); $maxBonus = 3; $maxScore = ($intWordLen * 2) + $maxBonus; $LCS = spell_similar($subAr3['word'], $strSimilarWord); $score = ($maxBonus - abs($intWordLen - $intSimilarWordLen) + $LCS * $maxBonus) / ($maxScore); $dblSimilarity = round($score, 10); while (array_key_exists("$dblSimilarity", $dblSimilarityArray)) { $dblSimilarity += .0000000001; } $dblSimilarityArray["$dblSimilarity"] = $strSimilarWord; } $subArPoss3 = $dblSimilarityArray; // Sort array by key value (score) krsort($dblSimilarityArray); reset($dblSimilarityArray); } } // Perpare JavaScript variables $jsOutput .= "msMissWordAr[$x] = new Array(4);\n"; $jsOutput .= "msMissWordAr[$x][0] = '".str_replace("\n", '', addslashes($subAr3['word']))."';\n"; $jsOutput .= "msMissWordAr[$x][1] = $oi;\n"; $jsOutput .= "msMissWordAr[$x][2] = '".str_replace(array('\n', "\n"), '<br />\n', trim(addslashes($context)))."';\n"; // Build suggestions array $sugCount = iif($intMaxSuggestions < count($dblSimilarityArray), $intMaxSuggestions, count($dblSimilarityArray)); echo 'Suggs: '.$sugCount.'<br />'; $jsOutput .= "msMissWordAr[$x][3] = new Array($sugCount);\n"; for ($l = 0; $l < $sugCount; $l++) { $jsOutput .= "msMissWordAr[$x][3][$l] = '".str_replace("\n", '', addslashes(current($dblSimilarityArray)))."';\n"; next($dblSimilarityArray); } // Cache this word if (!isset($doneSugsFor["$subAr3[word]"])) { $doneSugsFor["$subAr3[word]"] = $oi; } } // Build array of *ALL* words in text for ($x = 0; $x < count($words); $x++) { $jsOutput .= "msOrigWordAr[$x] = '".str_replace("\n", '\n', addslashes($words[$x]))."';\n"; } // Javascript: reload content frame with new frameset $jsOutput .= "parent.content.location = 'compose.spell.php?cmd=suggestions&sendafter=$sendAfter';\n"; } } // Javascript: if no words are misspelled, reload content frame with message page if (empty($jsOutput)) { $jsOutput .= "parent.content.location = 'compose.spell.php?cmd=noerrors';\n"; } //echo ' -->'; echo "End: ".(microdiff(STARTTIME) - $starttime)."<br />"; echo "Binary checks: $checks"; return $jsOutput;}function alert($text) { echo "<SCRIPT language=\"javascript\"> alert('$text'); </SCRIPT>";}######################################################## TEMPORARY TEMPLATE CODE #function gettemplate($template_name) { $template = @implode('', @file("./$template_name.html")); $template = parse_conditionals($template); return str_replace("\'", '\'', $template);}function makeeval($varname, $templatename = '', $add = false, $dieonecho = true, $comments = true) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -