The Singleton design pattern creates a class that can only have one instance. This is useful for tasks such as creating a globally available database connection for your script.
The prototype for the singleton class, in PHP, goes like this:
Singleton Pattern
class ClassName { static $instance = NULL; private function __construct() {} private function __clone() {} static function getInstance() { if(self::$instance === NULL) self::$instance = new ClassName(); return self::$instance; }
$obj = ClassName::getInstance();}
In PHP, variables have scope restrictions that prevent them from being visible in all parts of your program. We often need these variables inside classes and functions, for example. One way to provide globally accessible variables is to pass them into classes or functions as parameters. This method makes it clear that the function of class method is dependent on an external variable or object. Here’s an example:
Option #1: Pass the Variable As A Parameter
Here’s an example of passing a database handle into a hypothetical function and into a class.
function logger($info, $dbhandle);
class Logger { static $handle = NULL; static function logIt($info, $dbhandle) { self::$handle = $dbhandle; }}
When you have only a few parameters this tactic works fine, but if your functions have many parameters the result is unwieldly code. It is not uncommon to find programmers creating functions or methods that have parameteritis, with dozens of confusing parameters.
Fortunately, a singleton class provides a cleaner solution: it provides global availability of a single object—with the side-effect that the sole object cannot be modified. If we want to ensure that this class cannot be cloned or sub-classed, we will mark it as final and the construct() and clone() methods as protected.
Option #2: Use a Singleton Class
Here’s an example a properly formed singleton class that cannot be cloned or sub-classed, ensuring that there will only be one instance of this class.
final class DbConnection {
private static $handle = null; private static $instance = NULL; private static $db = 'default.db';
// Deny new DbConnection(); private function __construct($db = NULL) {}
// We deny cloning, as with: // $instance = DbConnection::connect(); // $clone = $instance; private function __clone() {}
function connect() { if(is_null(self::$handle)) { if(defined('DEFAULT_DB') { self::$db = DEFAULT_DB; } // Create the only possible instance of this class self::$handle = new SqliteDatabase(self::$db); } return self::$handle; }
static function getInstance() { if(self::$instance === NULL) { self::$instance = new DbConnection(); } return self::$instance; }}
This class encapsulates the entire process of creating the single instance and the database handle, and checks to see if a default database constant exists. We can use it this way:
class Logger { // Notice that this, too, is a singleton pattern class. static private $logger = NULL;
static function logIt($it) { $dbc = DbConnection::getInstance()->connect(); if(self::$instance == NULL) { self::$instance = new Logger); } }
private function __construct() {}
}
Refactoring
Since the sole function of the DbConnection class is to provide a database connection, we can simplify the code considerably by eliminating the getInstance() method:
final class DbConnection {
private static $handle = null; private static $db = 'default.db';
// Deny new DbConnection(); private function __construct($db = NULL) {}
// We deny cloning private function __clone() {}
function connect() { if(is_null(self::$handle)) { if(defined('DEFAULT_DB') { self::$db = DEFAULT_DB; } // Create the only possible instance of this class self::$handle = new SqliteDatabase(self::$db); } return self::$handle; }
}
class Logger {
static private $logger = NULL;
static function logIt($it) { $dbc = DbConnection::connect(); if(self::$instance == NULL) { self::$instance = new Logger); } }
private function __construct() {}
}
Happy hacking…
I teach PHP, Perl, and Ruby at CCSF, and every semester I hear some wild statements from students. Since most of my students are adults with degrees from prestigious universities, and many of them have achieved some success in fields unrelated to programming, they seem to think that their expertise in project management, or web design entitles them to easy success in an introductory programming course. Here are some of the things I hear.
- “My multimedia instructor told me that PHP will be easy to learn since I’m an HTML and CSS maven.”
- “I’m a Dreamweaver professional, so I’m sure PHP will be a no-brainer for me.”
- “My roommate works at Yahoo. I hear her talking to her friends about programming and I’ve picked up PHP by osmosis.”
- “I took a C course 20 years-ago, but I never use it. Anyway, I’m sure I’ll be fine with PHP.”
- “PHP is just shell scripting, so I’ll do the assignments using shell.”
- “I have a CS degree. I can write a compiler in assembler. I’ve programmed mainframes and I know 20 languages, including ALGOL and LISP. I can learn PHP in my sleep. Just one question, what is this HTML stuff?”
- “I’m going to build a website like YouTube or Google. I want to use PHP or Java. Which one should I learn?”
- “I don’t know anything about programming, but I’m very smart. And I work very hard. There shouldn’t be any problem. What is HTML again?”
My favorite way of learning anything new is definitely #3: osmosis. It rocks.
Keep hacking…
The Registry design pattern gives us a way to overcome scoping complexities in your object-oriented programs. In this post I want to talk about how we use a Registry class in the MojoMVC.
PHP Scope: Main, Class, and Method
Though my diagram looks like the interior of a single-celled animal, I mean to suggest that the attributes inside classes are encapsulated within impermeable walls. And that classes are impermeable to the global variables in Main. This is a good thing in OOP Land.
In the MojoMVC, every request requires a Request object. There are times when other objects need that information. PHP has global variables by default, with local variables inside regular functions, and public, protected, and private methods inside classes. Since we don’t speak Kludge here, we need a another strategy for passing information around. The Registry pattern fills the bill.
We use the Registry class to take advantge the fact that classes have super global visibility—they can walk through walls like the super global variables ($_GET, $_POST, etc), functions, and constants. In other words, our Registry class can function as a super global delivery messenger as long as we give it some static setters and getters.
The Registry Class
1 class Registry extends Base {
2 static private $data = array();
3
4 private function __construct() {}
5
6 static public function get($key)
7 {
8 return self::$data[$key];
9 }
10
11 static public function set($key,$value)
12 {
13 self::$data[$key] = $value;
14 }
15 }
We can use it like this:
Registry::set(‘string’, ‘this is the name’);
print Registry::get(‘string’); // output: this is the name
class NextClass {
function __construct() {
print Registry::get(‘string’);
}
}
$n = new NextClass; // output: this is the name
Now we have a class that walks through walls to deliver the values stored inside it. All we have to do is store the Request object in the Registry, like this:
Registry::set(‘request’, $this->r);
You’re probably wondering where $this->r came from. That’s an interesting story, but it will have to wait until next time.
For more information on the Registry pattern, check out your friendly Google.
I’m lazy when it comes to writing valid HTML. I know it’s the right thing to do, but I’ve developed some bad habits over the years. There are too many times when I forget quotes, alt tags, and ending tags. So I’ve decided to outsource my HTML generation to a machine: Textile.
Textile is a “human web text generator”. I like Textile because I can use simple formatting cues to generate any HTML you want. A simple example would be,
p. This is a paragraph. "A link to a URL":http://someurl
Textile will turn that text into this HTML:
<p>This is a paragraph. <a href="http://someurl">A link to a <spanclass="caps">URL</span></a></p>
In my CCSF courses I’ve developed a small PHP framework that I use as a teaching tool for my advanced PHP course. I call it MojoMVC. MojoMVC generates output of any kind by employing Decorator classes to format the output. The default format is HTML, but Decorators can be of any kind, including XML, PDF, images, and so on. All you have to do is write the class for the format you want. I created a HTMLDecorator class to have Textile ease my HTML woes.
MojoMVC Overview:
- MojoMVC is a conventional MVC framework that receives a request for the URL http://you.com/cs130a/syllabus.
- Controller classes are mapped to URLs.
- Which means, there is a cs130aController class and a syllabus page to be displayed.
- Every controller class has a render method defined in the parent class, ApplicationController.
- Every render method uses a Decorator class to format output.
The render in ApplicationController looks like this:
1 class ApplicationController extends Base {
2 // snip //
3 function render() {
4 // Default is HTMLDecorator
5 $klass = $this->as.'Decorator';
6 // Decorators all have a render()
7 $decorator = new $klass;
8 // Pass the current instance to the decorator for rendering.
9 $decorator->render($this) ;
10 exit;
11 }
12 }
By the way, one of PHP’s Good Parts in visible in this method—the easy implementation of polymorphism in lines 5, 7, and 9.
After we define the render method, the next step is to create a Decorator that will take the current instance and render its output using Textile. Here’s how it works.
The MojoMVC HTMLDecorator
1 class HTMLDecorator
2 {
3
4 function render($klass)
5 { // $klass is instance of current controller
6 $textile = new Textile; // new Textile object
7 // Check to make sure we have the requested object
8 if (file_exists(VIEWS.$klass->r->controller.'/'.$klass->r->action.'.html'))
9 {
10 // If so, run the method requested
11 if (method_exists($klass->r->controller.'Controller', $klass->r->action))
12 {
13 $action = $klass->r->action;
14 $klass->$action();
15 }
16 // Buffer output so we can pass it to Textile
17 ob_start();
18 include (VIEWS.$klass->r->controller.'/'.$klass->r->action.'.html');
19 // Textileize the HTML
20 $klass->out = $textile->textileThis(ob_get_clean());
21 } else
22 {
23 include (VIEWS.$klass->r->controller.'/'.$klass->r->error404.'.html');
24 }
25 // Include the layout HTML file that displays the requested page.
26 if (file_exists(LAYOUTS.$klass->r->controller.'.html'))
27 {
28 include LAYOUTS.$klass->r->controller.'.html';
29 } elseif (file_exists(LAYOUTS.'default.html'))
30 {
31 include LAYOUTS.'default.html';
32 } else
33 {
34 print $klass->out;
35 }
36 }
37 }
Most of this code is all about error checking. Textileizing is a matter of saving the output (using ob_start and ob_get_clean), loading Textile, creating an instance, and running the text through the textileThis method.
To learn more about Textile, check out the Textile home page. Textile has been ported to Ruby, where it is known as RedCloth.
For an easy-to-digest introduction to the Decorator design pattern, check out the Head First Design Patterns sample chapter.
Happy hacking…
Have you noticed that your Drupal app feels sluggish? Here’s a visual map of the wheel-spinning Drupal goes through to say “Hello, World”. It’s impressive and depressing at the same time. Click on the image to see the whole story.
Part of the Very Big Picture
Like everyone else, I’ve created an MVC framework (MojoMVC). Depending on the circumstances, I sometimes do it in PHP and sometimes in Ruby. Since this is a light weight site, I don’t think it really matters much which language I choose. Of course, Ruby has a sweeter syntax. And PHP has a ton of convenience. Both work fine.
One of the design principles I favor is that my sites be able to land on the feet and run without outside help. PHP has SQLite3 embedded in it and suits my purposes. If I use Ruby, I need to know that SQLite3 is installed. This has been a problem on the CCSF servers, where HP-UX makes everyone miserable.
I know that SQLite can’t handle big-time traffic, but I’m fine with that. I’m a low traffic guy. When the day comes that I’m getting a 1,000,000 hits a day, I’ll add in support for PostgreSQL.
The Model component of MojoMVC uses my home-rolled ORM class, SQLiteActiveRecord. This may sound weird to non-programmers, but I really love the idea of the ActiveRecord class for my projects. A simple RESTful interface is fine for me. And I’m not building Twitter or Wikipedia, so I’m not the least bit concerned with speed.
When I get a Round Tuit, I’ll start posting some of the code I’ve written. In the meantime, I’ll continue to share my software tools with my PHP classes at CCSF.
This is a list of the 100 most common built-in PHP functions, and the 100 most common Drupal functions in the Drupal source code. Language constructs and reserved words are excluded from the count (foreach, for, while, list, isset, etc).
Total Built-in Functions Used: 239
Total Built-in Function calls in Drupal source code: 1392.
| Rank |
Function |
Occurrences |
Per Cent |
| 1 |
define |
94 |
6.75 |
| 2 |
implode |
79 |
5.68 |
| 3 |
array_merge |
63 |
4.53 |
| 4 |
substr |
58 |
4.17 |
| 5 |
trim |
38 |
2.73 |
| 6 |
str_replace |
38 |
2.73 |
| 7 |
count |
37 |
2.66 |
| 8 |
preg_replace |
35 |
2.51 |
| 9 |
array_pop |
33 |
2.37 |
| 10 |
array_shift |
31 |
2.23 |
| 11 |
explode |
30 |
2.16 |
| 12 |
ini_set |
29 |
2.08 |
| 13 |
header |
27 |
1.94 |
| 14 |
urldecode |
23 |
1.65 |
| 15 |
call_user_func_array |
22 |
1.58 |
| 16 |
func_get_args |
21 |
1.51 |
| 17 |
chr |
17 |
1.22 |
| 18 |
array_keys |
16 |
1.15 |
| 19 |
array_unshift |
15 |
1.08 |
| 20 |
preg_match |
15 |
1.08 |
| 21 |
preg_replace_callback |
15 |
1.08 |
| 22 |
in_array |
15 |
1.08 |
| 23 |
is_array |
14 |
1.01 |
| 24 |
strtr |
14 |
1.01 |
| 25 |
array_filter |
13 |
0.93 |
| 26 |
strpos |
12 |
0.86 |
| 27 |
md5 |
12 |
0.86 |
| 28 |
parse_url |
12 |
0.86 |
| 29 |
dirname |
11 |
0.79 |
| 30 |
unserialize |
11 |
0.79 |
| 31 |
max |
11 |
0.79 |
| 32 |
gmdate |
10 |
0.72 |
| 33 |
strlen |
9 |
0.65 |
| 34 |
printf |
9 |
0.65 |
| 35 |
time |
9 |
0.65 |
| 36 |
pg_query |
9 |
0.65 |
| 37 |
serialize |
8 |
0.57 |
| 38 |
round |
8 |
0.57 |
| 39 |
array_walk |
8 |
0.57 |
| 40 |
array_flip |
8 |
0.57 |
| 41 |
date |
8 |
0.57 |
| 42 |
array_unique |
8 |
0.57 |
| 43 |
ksort |
8 |
0.57 |
| 44 |
str_repeat |
7 |
0.50 |
| 45 |
mysqli_query |
7 |
0.50 |
| 46 |
array_map |
7 |
0.50 |
| 47 |
asort |
7 |
0.50 |
| 48 |
mysql_query |
7 |
0.50 |
| 49 |
file_get_contents |
6 |
0.43 |
| 50 |
function_exists |
6 |
0.43 |
| 51 |
register_shutdown_function |
6 |
0.43 |
| 52 |
array_reverse |
6 |
0.43 |
| 53 |
ceil |
5 |
0.36 |
| 54 |
fclose |
5 |
0.36 |
| 55 |
urlencode |
5 |
0.36 |
| 56 |
xml_parser_create |
5 |
0.36 |
| 57 |
uasort |
5 |
0.36 |
| 58 |
file |
5 |
0.36 |
| 59 |
strstr |
5 |
0.36 |
| 60 |
basename |
5 |
0.36 |
| 61 |
base64_encode |
5 |
0.36 |
| 62 |
bcmod |
5 |
0.36 |
| 63 |
min |
5 |
0.36 |
| 64 |
strtolower |
5 |
0.36 |
| 65 |
floor |
4 |
0.29 |
| 66 |
array_merge_recursive |
4 |
0.29 |
| 67 |
array_slice |
4 |
0.29 |
| 68 |
preg_match_all |
4 |
0.29 |
| 69 |
ob_start |
4 |
0.29 |
| 70 |
mysql_connect |
4 |
0.29 |
| 71 |
abs |
4 |
0.29 |
| 72 |
realpath |
4 |
0.29 |
| 73 |
ltrim |
4 |
0.29 |
| 74 |
mail |
4 |
0.29 |
| 75 |
preg_split |
4 |
0.29 |
| 76 |
base64_decode |
4 |
0.29 |
| 77 |
chmod |
4 |
0.29 |
| 78 |
array_key_exists |
4 |
0.29 |
| 79 |
call_user_func |
4 |
0.29 |
| 80 |
ob_end_clean |
4 |
0.29 |
| 81 |
ord |
4 |
0.29 |
| 82 |
array_values |
3 |
0.22 |
| 83 |
is_numeric |
3 |
0.22 |
| 84 |
xml_parser_free |
3 |
0.22 |
| 85 |
debug_backtrace |
3 |
0.22 |
| 86 |
pg_last_error |
3 |
0.22 |
| 87 |
is_dir |
3 |
0.22 |
| 88 |
intval |
3 |
0.22 |
| 89 |
xml_set_character_data_handler |
3 |
0.22 |
| 90 |
is_string |
3 |
0.22 |
| 91 |
stripslashes |
3 |
0.22 |
| 92 |
sort |
3 |
0.22 |
| 93 |
fopen |
3 |
0.22 |
| 94 |
ini_get |
3 |
0.22 |
| 95 |
xml_set_element_handler |
3 |
0.22 |
| 96 |
trigger_error |
3 |
0.22 |
| 97 |
extract |
3 |
0.22 |
| 98 |
is_object |
3 |
0.22 |
| 99 |
array_diff |
3 |
0.22 |
| 100 |
link |
3 |
0.22 |
Total Drupal Functions Used: 1647
Total Custom Drupal Function calls in Drupal source code: 6819.
| Rank |
Function |
Occurrences |
Per Cent |
| 1 |
t |
1133 |
16.62 |
| 2 |
theme |
273 |
4.00 |
| 3 |
db_query |
230 |
3.37 |
| 4 |
drupal_set_message |
214 |
3.14 |
| 5 |
variable_get |
148 |
2.17 |
| 6 |
drupal_render |
113 |
1.66 |
| 7 |
form_set_error |
89 |
1.31 |
| 8 |
check_plain |
80 |
1.17 |
| 9 |
watchdog |
78 |
1.14 |
| 10 |
l |
73 |
1.07 |
| 11 |
st |
68 |
1.00 |
| 12 |
drupal_set_title |
66 |
0.97 |
| 13 |
drupal_get_form |
59 |
0.87 |
| 14 |
variable_set |
52 |
0.76 |
| 15 |
system_settings_form |
43 |
0.63 |
| 16 |
cache_clear_all |
43 |
0.63 |
| 17 |
update_sql |
40 |
0.59 |
| 18 |
drupal_goto |
39 |
0.57 |
| 19 |
drupal_add_js |
38 |
0.56 |
| 20 |
db_result |
34 |
0.50 |
| 21 |
url |
34 |
0.50 |
| 22 |
theme_get_setting |
33 |
0.48 |
| 23 |
confirm_form |
32 |
0.47 |
| 24 |
base_path |
27 |
0.40 |
| 25 |
pager_query |
27 |
0.40 |
| 26 |
drupal_add_css |
27 |
0.40 |
| 27 |
module_invoke |
27 |
0.40 |
| 28 |
format_date |
26 |
0.38 |
| 29 |
check_url |
26 |
0.38 |
| 30 |
drupal_not_found |
25 |
0.37 |
| 31 |
db_fetch_object |
25 |
0.37 |
| 32 |
module_invoke_all |
22 |
0.32 |
| 33 |
drupal_attributes |
19 |
0.28 |
| 34 |
drupal_alter |
19 |
0.28 |
| 35 |
drupal_map_assoc |
19 |
0.28 |
| 36 |
db_query_range |
18 |
0.26 |
| 37 |
language_list |
17 |
0.25 |
| 38 |
get_t |
17 |
0.25 |
| 39 |
drupal_add_tabledrag |
17 |
0.25 |
| 40 |
xmlrpc_error |
17 |
0.25 |
| 41 |
language_default |
16 |
0.23 |
| 42 |
arg |
16 |
0.23 |
| 43 |
template_preprocess |
16 |
0.23 |
| 44 |
_locale_import_message |
15 |
0.22 |
| 45 |
format_plural |
15 |
0.22 |
| 46 |
stdClass |
15 |
0.22 |
| 47 |
_user_mail_text |
14 |
0.21 |
| 48 |
drupal_bootstrap |
14 |
0.21 |
| 49 |
menu_get_item |
14 |
0.21 |
| 50 |
drupal_set_header |
13 |
0.19 |
| 51 |
menu_rebuild |
13 |
0.19 |
| 52 |
cache_set |
12 |
0.18 |
| 53 |
db_add_field |
12 |
0.18 |
| 54 |
_db_query |
12 |
0.18 |
| 55 |
form_error |
12 |
0.18 |
| 56 |
variable_del |
12 |
0.18 |
| 57 |
db_fetch_array |
12 |
0.18 |
| 58 |
module_list |
12 |
0.18 |
| 59 |
drupal_mail |
11 |
0.16 |
| 60 |
drupal_get_destination |
11 |
0.16 |
| 61 |
drupal_load |
11 |
0.16 |
| 62 |
batch_process |
11 |
0.16 |
| 63 |
batch_get |
11 |
0.16 |
| 64 |
drupal_access_denied |
11 |
0.16 |
| 65 |
hook_schema |
10 |
0.15 |
| 66 |
form_set_value |
10 |
0.15 |
| 67 |
_db_query_callback |
10 |
0.15 |
| 68 |
node_load |
9 |
0.13 |
| 69 |
node_get_types |
9 |
0.13 |
| 70 |
module_rebuild_cache |
9 |
0.13 |
| 71 |
menu_link_save |
9 |
0.13 |
| 72 |
file_directory_path |
9 |
0.13 |
| 73 |
form_clean_id |
9 |
0.13 |
| 74 |
conf_path |
9 |
0.13 |
| 75 |
image_get_info |
9 |
0.13 |
| 76 |
update_get_projects |
9 |
0.13 |
| 77 |
db_change_field |
9 |
0.13 |
| 78 |
drupal_json |
8 |
0.12 |
| 79 |
file_scan_directory |
8 |
0.12 |
| 80 |
batch_set |
8 |
0.12 |
| 81 |
_form_set_class |
8 |
0.12 |
| 82 |
cache_get |
8 |
0.12 |
| 83 |
module_load_include |
8 |
0.12 |
| 84 |
tablesort_sql |
8 |
0.12 |
| 85 |
install_task_list |
8 |
0.12 |
| 86 |
_db_create_key_sql |
8 |
0.12 |
| 87 |
_db_error_page |
8 |
0.12 |
| 88 |
drupal_get_normal_path |
8 |
0.12 |
| 89 |
b |
8 |
0.12 |
| 90 |
hook_forms |
7 |
0.10 |
| 91 |
drupal_maintenance_theme |
7 |
0.10 |
| 92 |
drupal_set_content |
7 |
0.10 |
| 93 |
module_load_install |
7 |
0.10 |
| 94 |
file_create_path |
7 |
0.10 |
| 95 |
drupal_query_string_encode |
7 |
0.10 |
| 96 |
menu_link_delete |
7 |
0.10 |
| 97 |
_db_create_field_sql |
7 |
0.10 |
| 98 |
menu_execute_active_handler |
7 |
0.10 |
| 99 |
module_exists |
7 |
0.10 |
| 100 |
_locale_get_predefined_list |
7 |
0.10 |
This is a list of the 100 most common built-in PHP functions, and the 100 most common Drupal functions in the Drupal source code. Language constructs and reserved words are excluded from the count (foreach, for, while, list, isset, etc).
There were 1350 calls to 235 built-in functions in the source code, and 5483 calls to 1032 DRUPAL functions.
The Top 100 Built-in PHP Functions in Drupal
| Rank |
Function |
Occurrences |
Per Cent |
| 1 |
define |
94 |
6.75 |
| 2 |
implode |
79 |
5.68 |
| 3 |
array_merge |
63 |
4.53 |
| 4 |
substr |
58 |
4.17 |
| 5 |
trim |
38 |
2.73 |
| 6 |
str_replace |
38 |
2.73 |
| 7 |
count |
37 |
2.66 |
| 8 |
preg_replace |
35 |
2.51 |
| 9 |
array_pop |
33 |
2.37 |
| 10 |
array_shift |
31 |
2.23 |
| 11 |
explode |
30 |
2.16 |
| 12 |
ini_set |
29 |
2.08 |
| 13 |
header |
27 |
1.94 |
| 14 |
urldecode |
23 |
1.65 |
| 15 |
call_user_func_array |
22 |
1.58 |
| 16 |
func_get_args |
21 |
1.51 |
| 17 |
chr |
17 |
1.22 |
| 18 |
array_keys |
16 |
1.15 |
| 19 |
array_unshift |
15 |
1.08 |
| 20 |
preg_match |
15 |
1.08 |
| 21 |
preg_replace_callback |
15 |
1.08 |
| 22 |
in_array |
15 |
1.08 |
| 23 |
is_array |
14 |
1.01 |
| 24 |
strtr |
14 |
1.01 |
| 25 |
array_filter |
13 |
0.93 |
| 26 |
strpos |
12 |
0.86 |
| 27 |
md5 |
12 |
0.86 |
| 28 |
parse_url |
12 |
0.86 |
| 29 |
dirname |
11 |
0.79 |
| 30 |
unserialize |
11 |
0.79 |
| 31 |
max |
11 |
0.79 |
| 32 |
gmdate |
10 |
0.72 |
| 33 |
strlen |
9 |
0.65 |
| 34 |
printf |
9 |
0.65 |
| 35 |
time |
9 |
0.65 |
| 36 |
pg_query |
9 |
0.65 |
| 37 |
serialize |
8 |
0.57 |
| 38 |
round |
8 |
0.57 |
| 39 |
array_walk |
8 |
0.57 |
| 40 |
array_flip |
8 |
0.57 |
| 41 |
date |
8 |
0.57 |
| 42 |
array_unique |
8 |
0.57 |
| 43 |
ksort |
8 |
0.57 |
| 44 |
str_repeat |
7 |
0.50 |
| 45 |
mysqli_query |
7 |
0.50 |
| 46 |
array_map |
7 |
0.50 |
| 47 |
asort |
7 |
0.50 |
| 48 |
mysql_query |
7 |
0.50 |
| 49 |
file_get_contents |
6 |
0.43 |
| 50 |
function_exists |
6 |
0.43 |
| 51 |
register_shutdown_function |
6 |
0.43 |
| 52 |
array_reverse |
6 |
0.43 |
| 53 |
ceil |
5 |
0.36 |
| 54 |
fclose |
5 |
0.36 |
| 55 |
urlencode |
5 |
0.36 |
| 56 |
xml_parser_create |
5 |
0.36 |
| 57 |
uasort |
5 |
0.36 |
| 58 |
file |
5 |
0.36 |
| 59 |
strstr |
5 |
0.36 |
| 60 |
basename |
5 |
0.36 |
| 61 |
base64_encode |
5 |
0.36 |
| 62 |
bcmod |
5 |
0.36 |
| 63 |
min |
5 |
0.36 |
| 64 |
strtolower |
5 |
0.36 |
| 65 |
floor |
4 |
0.29 |
| 66 |
array_merge_recursive |
4 |
0.29 |
| 67 |
array_slice |
4 |
0.29 |
| 68 |
preg_match_all |
4 |
0.29 |
| 69 |
ob_start |
4 |
0.29 |
| 70 |
mysql_connect |
4 |
0.29 |
| 71 |
abs |
4 |
0.29 |
| 72 |
realpath |
4 |
0.29 |
| 73 |
ltrim |
4 |
0.29 |
| 74 |
mail |
4 |
0.29 |
| 75 |
preg_split |
4 |
0.29 |
| 76 |
base64_decode |
4 |
0.29 |
| 77 |
chmod |
4 |
0.29 |
| 78 |
array_key_exists |
4 |
0.29 |
| 79 |
call_user_func |
4 |
0.29 |
| 80 |
ob_end_clean |
4 |
0.29 |
| 81 |
ord |
4 |
0.29 |
| 82 |
array_values |
3 |
0.22 |
| 83 |
is_numeric |
3 |
0.22 |
| 84 |
xml_parser_free |
3 |
0.22 |
| 85 |
debug_backtrace |
3 |
0.22 |
| 86 |
pg_last_error |
3 |
0.22 |
| 87 |
is_dir |
3 |
0.22 |
| 88 |
intval |
3 |
0.22 |
| 89 |
xml_set_character_data_handler |
3 |
0.22 |
| 90 |
is_string |
3 |
0.22 |
| 91 |
stripslashes |
3 |
0.22 |
| 92 |
sort |
3 |
0.22 |
| 93 |
fopen |
3 |
0.22 |
| 94 |
ini_get |
3 |
0.22 |
| 95 |
xml_set_element_handler |
3 |
0.22 |
| 96 |
trigger_error |
3 |
0.22 |
| 97 |
extract |
3 |
0.22 |
| 98 |
is_object |
3 |
0.22 |
| 99 |
array_diff |
3 |
0.22 |
| 100 |
link |
3 |
0.22 |
Total Drupal Functions Used: 1647
Total Custom Drupal Function calls in Drupal source code: 6819.
The Top 100 Drupal Native Functions
| Rank |
Function |
Occurrences |
Per Cent |
| 1 |
t |
1133 |
16.62 |
| 2 |
theme |
273 |
4.00 |
| 3 |
db_query |
230 |
3.37 |
| 4 |
drupal_set_message |
214 |
3.14 |
| 5 |
variable_get |
148 |
2.17 |
| 6 |
drupal_render |
113 |
1.66 |
| 7 |
form_set_error |
89 |
1.31 |
| 8 |
check_plain |
80 |
1.17 |
| 9 |
watchdog |
78 |
1.14 |
| 10 |
l |
73 |
1.07 |
| 11 |
st |
68 |
1.00 |
| 12 |
drupal_set_title |
66 |
0.97 |
| 13 |
drupal_get_form |
59 |
0.87 |
| 14 |
variable_set |
52 |
0.76 |
| 15 |
system_settings_form |
43 |
0.63 |
| 16 |
cache_clear_all |
43 |
0.63 |
| 17 |
update_sql |
40 |
0.59 |
| 18 |
drupal_goto |
39 |
0.57 |
| 19 |
drupal_add_js |
38 |
0.56 |
| 20 |
db_result |
34 |
0.50 |
| 21 |
url |
34 |
0.50 |
| 22 |
theme_get_setting |
33 |
0.48 |
| 23 |
confirm_form |
32 |
0.47 |
| 24 |
base_path |
27 |
0.40 |
| 25 |
pager_query |
27 |
0.40 |
| 26 |
drupal_add_css |
27 |
0.40 |
| 27 |
module_invoke |
27 |
0.40 |
| 28 |
format_date |
26 |
0.38 |
| 29 |
check_url |
26 |
0.38 |
| 30 |
drupal_not_found |
25 |
0.37 |
| 31 |
db_fetch_object |
25 |
0.37 |
| 32 |
module_invoke_all |
22 |
0.32 |
| 33 |
drupal_attributes |
19 |
0.28 |
| 34 |
drupal_alter |
19 |
0.28 |
| 35 |
drupal_map_assoc |
19 |
0.28 |
| 36 |
db_query_range |
18 |
0.26 |
| 37 |
language_list |
17 |
0.25 |
| 38 |
get_t |
17 |
0.25 |
| 39 |
drupal_add_tabledrag |
17 |
0.25 |
| 40 |
xmlrpc_error |
17 |
0.25 |
| 41 |
language_default |
16 |
0.23 |
| 42 |
arg |
16 |
0.23 |
| 43 |
template_preprocess |
16 |
0.23 |
| 44 |
_locale_import_message |
15 |
0.22 |
| 45 |
format_plural |
15 |
0.22 |
| 46 |
stdClass |
15 |
0.22 |
| 47 |
_user_mail_text |
14 |
0.21 |
| 48 |
drupal_bootstrap |
14 |
0.21 |
| 49 |
menu_get_item |
14 |
0.21 |
| 50 |
drupal_set_header |
13 |
0.19 |
| 51 |
menu_rebuild |
13 |
0.19 |
| 52 |
cache_set |
12 |
0.18 |
| 53 |
db_add_field |
12 |
0.18 |
| 54 |
_db_query |
12 |
0.18 |
| 55 |
form_error |
12 |
0.18 |
| 56 |
variable_del |
12 |
0.18 |
| 57 |
db_fetch_array |
12 |
0.18 |
| 58 |
module_list |
12 |
0.18 |
| 59 |
drupal_mail |
11 |
0.16 |
| 60 |
drupal_get_destination |
11 |
0.16 |
| 61 |
drupal_load |
11 |
0.16 |
| 62 |
batch_process |
11 |
0.16 |
| 63 |
batch_get |
11 |
0.16 |
| 64 |
drupal_access_denied |
11 |
0.16 |
| 65 |
hook_schema |
10 |
0.15 |
| 66 |
form_set_value |
10 |
0.15 |
| 67 |
_db_query_callback |
10 |
0.15 |
| 68 |
node_load |
9 |
0.13 |
| 69 |
node_get_types |
9 |
0.13 |
| 70 |
module_rebuild_cache |
9 |
0.13 |
| 71 |
menu_link_save |
9 |
0.13 |
| 72 |
file_directory_path |
9 |
0.13 |
| 73 |
form_clean_id |
9 |
0.13 |
| 74 |
conf_path |
9 |
0.13 |
| 75 |
image_get_info |
9 |
0.13 |
| 76 |
update_get_projects |
9 |
0.13 |
| 77 |
db_change_field |
9 |
0.13 |
| 78 |
drupal_json |
8 |
0.12 |
| 79 |
file_scan_directory |
8 |
0.12 |
| 80 |
batch_set |
8 |
0.12 |
| 81 |
_form_set_class |
8 |
0.12 |
| 82 |
cache_get |
8 |
0.12 |
| 83 |
module_load_include |
8 |
0.12 |
| 84 |
tablesort_sql |
8 |
0.12 |
| 85 |
install_task_list |
8 |
0.12 |
| 86 |
_db_create_key_sql |
8 |
0.12 |
| 87 |
_db_error_page |
8 |
0.12 |
| 88 |
drupal_get_normal_path |
8 |
0.12 |
| 89 |
b |
8 |
0.12 |
| 90 |
hook_forms |
7 |
0.10 |
| 91 |
drupal_maintenance_theme |
7 |
0.10 |
| 92 |
drupal_set_content |
7 |
0.10 |
| 93 |
module_load_install |
7 |
0.10 |
| 94 |
file_create_path |
7 |
0.10 |
| 95 |
drupal_query_string_encode |
7 |
0.10 |
| 96 |
menu_link_delete |
7 |
0.10 |
| 97 |
_db_create_field_sql |
7 |
0.10 |
| 98 |
menu_execute_active_handler |
7 |
0.10 |
| 99 |
module_exists |
7 |
0.10 |
| 100 |
_locale_get_predefined_list |
7 |
0.10 |