1<?php 2/* 3 4 This page is either directly called from the browser, in 5 which case it will always show the full list of "functions" 6 in the user's preferred language version of the PHP 7 documentation. 8 9 In other cases this file is included from manual-lookup.php, 10 which sets $notfound, so we know what function to search for, 11 and display results for that search. 12 13*/ 14 15// Ensure that our environment is set up 16$_SERVER['BASE_PAGE'] = 'quickref.php'; 17include_once __DIR__ . '/include/prepend.inc'; 18include_once __DIR__ . '/include/errors.inc'; 19 20if (empty($notfound)) { 21 mirror_redirect("/search.php"); 22} 23 24// Print out the table of found (or all) functions. The HTML comments are 25// needed to support MyCroft search (Mozilla browser family and Sherlock for MacOSX) 26function quickref_table($functions, $sort = true): void 27{ 28 global $LANG; 29 30 echo "<!-- result list start -->\n"; 31 echo "<ul id=\"quickref_functions\">\n"; 32 // Prepare the data 33 if ($sort) { 34 asort($functions); 35 } 36 37 // Print out all rows 38 foreach ($functions as $file => $name) { 39 echo "<li><a href=\"/manual/$LANG/$file\">$name</a></li>\n"; 40 } 41 echo "</ul>\n"; 42 echo "<!-- result list end -->\n"; 43} 44 45// Open directory, fall back to English, 46// if there is no dir for that language 47$dirh = @opendir($_SERVER['DOCUMENT_ROOT'] . "/manual/$LANG"); 48if (!$dirh) { 49 error_noservice(); 50} 51 52$functions = $maybe = $temp = $parts = []; 53$p = 0; 54 55// Get all file names from the directory 56while (($entry = readdir($dirh)) !== false) { 57 58 // Skip names starting with a dot 59 if (substr($entry, 0, 1) == ".") { continue; } 60 61 // For function and class pages, get the name out 62 if (preg_match('!^(function|class)\.(.+)\.php$!', $entry, $parts)) { 63 $funcname = str_replace('-', '_', $parts[2]); 64 $functions[$entry] = $funcname; 65 66 // Compute similarity of the name to the requested one 67 if (function_exists('similar_text') && !empty($notfound)) { 68 similar_text($funcname, $notfound, $p); 69 70 // If $notfound is a substring of $funcname then overwrite the score 71 // similar_text() gave it. 72 if ($p < 70 && ($pos = strpos($funcname, $notfound)) !== false) { 73 $p = 90 - $pos; 74 } 75 $temp[$entry] = $p; 76 } 77 } 78} 79closedir($dirh); 80 81// We have found file names 82if (count($temp) > 0) { 83 84 // Sort names by percentage 85 arsort($temp); 86 87 // Collect SHOW_CLOSE number of names from the top 88 foreach ($temp as $file => $p) { 89 90 // Stop, if we found enough matches 91 if (count($maybe) >= 30) { break; } 92 93 // If the two are more then 70% similar or $notfound is a substring 94 // of $funcname, then the match is a very similar one 95 if ($p >= 70 || (strpos($functions[$file], $notfound) !== false)) { 96 $maybe[$file] = '<b>' . $functions[$file] . '</b>'; 97 } 98 // Otherwise it is just similar 99 else { 100 $maybe[$file] = $functions[$file]; 101 } 102 } 103 unset($matches, $temp); 104} 105 106// Do not index page if presented as a search result 107if (count($maybe) > 0) { $head_options = ["noindex"]; } 108else { $head_options = []; } 109 110site_header("Manual Quick Reference", $head_options + ["current" => "help"]); 111 112// Note: $notfound is defined (with htmlspecialchars) inside manual-lookup.php 113$notfound_enc = urlencode($notfound); 114 115if ($snippet = is_known_snippet($notfound)) { 116 echo "<h1>Related snippet found for '{$notfound}'</h1>"; 117 echo "<p>{$snippet}</p>"; 118} 119 120?> 121 122<h1>PHP Function List</h1> 123 124<?php if (!empty($notfound) && count($maybe) > 0) { ?> 125 126<p> 127 <b><?php echo $notfound; ?></b> doesn't exist. Closest matches: 128</p> 129 130<?php 131quickref_table($maybe, false); 132 133site_footer([ 134 "sidebar" => '<p class="panel"><a href="/search.php?show=all&pattern=' . $notfound_enc . '">Full website search</a>', 135]); 136} 137