Published under the Creative Commons Licence
by Artful Software Development
http://www.artfulsoftware.com
Version 1.73, 19 Feb 2013
TheUsual/PHP exists to provide a free, fast, user-friendly web browser viewing and maintenance interface for MySQL databases. It runs on your own computer under a web server like Apache or IIS, on a dedicated intranet or internet server, or on a remote hosting server (dedicated or shared) running MySQL 4 or preferably 5, or even 6.
There are two versions, one for the mysql API and the other, preferable one for the mysqli API.
TheUsual implements, in PHP 4-5 for MySQL 4-5-6, the Artful concept of TheUsual—the usual jobs you have to do to create, update & maintain database data. Like earlier versions of TheUsual for XBase and Sybase backends, and like its cousin for Visual Studio 2005 and MySQL, it implements a general-purpose viewing and maintenance interface for any available database and its tables:
The design and look-and-feel of TheUsual/PHP are described in Chapter 12 of Get it Done with MySQL 5, excerpted here.
To download TheUsual/PHP, visit http://www.artfulsoftware.com/theusual.html and scroll to the bottom of the page.
TheUsual/PHP requires:
There are two main PHP APIs for MySQL, mysql and mysqli, where 'i' means 'improved'. The corresponding versions of TheUsual/PHP are published in theUsualPHPmysql.rar and theUsualPHPmysqli.rar. If you write or invoke stored routines, the mysqli version is recommended; for an example of why, see "How to call a stored procedure with an OUT parameter" at http://www.paragon-cs.com/mag/issue3.pdf.
MySQL-PHP configuration has many moving parts. These are the best guides we know for getting them to work together:
Linux:
http://www.linuxhelp.net/guides/lamp/
http://hostlibrary.com/installing_apache_mysql_php_on_linux
Windows:
http://www.artfulsoftware.com/php_mysql_win.html
Windows with Apache web server:
http://forge.mysql.com/wiki/PhpFAQ
Windows with IIS
http://www.devarticles.com/c/a/Apache/Installing_PHP_under_Windows
http://www.devarticles.com/c/a/PHP/Installing-PHP-under-Windows-Further-Configuration-of-WAMP
Mac:
http://www.apachefriends.org/en/index.html
S1. Unpack
artful.bmp
art_ico.gif
download.php
phpinc.php
mysqlddl.php
mysqldel.php
mysqlins.php
mysqlupd.php
session_continue.php
theusual_start.php
theusual.php
theusual-funcs.php
viewupd.php
theusualcall.php
theusualcall.ini
into a conveniently named folder (eg, theusual ) off the Document Root of your web server (for example /var/www/theusual, /apache/htdocs/theusual/, or on Windows with IIS, c:/inetpub/wwwroot/theusual/ ).
S2. Unpack
theusual-login.php
into c:/php/includes if available, or failing that, in a directory that is not web-visible and that is visible to PHP.
S3. In theusual-login.php, edit the values of $host, $user and $pswd for your MySQL setup.
S4. In your browser run http://localhost/theusual/theusual_start.php, and bookmark the page.
W1. In your site's main web document folder (eg /home/your_site_name/public_html), create a folder named theusual. This folder will hold your web instance of TheUsual.
W2. Create a folder outside your web document tree, ie a folder that is not available via public_html, for example home/your_site_name/theusual. If your hosting provider does not provide access outside your document tree (unbelievably, some don't), get a better hosting provider right away!
W3. Visit http://www.tools.dynamicdrive.com/password/, and there enter the desired username and password for your instance of TheUsual. Usually, this will be the username and password provided by your hosting provider for access to your MySQL database. For 'Path to .htpasswd file', enter the full path to the folder you created in step W2. Click Submit.
W4. Save the indicated contents of .htaccess, which will look something like this...
AuthName "TheUsual"
AuthType Basic
AuthUserFile /home/your_site_name/theusual/.htpasswd
AuthGroupFile /dev/null
require valid-user
to a plain text file named .htaccess in the folder you made in step W1.
W5. Save the indicated contents of .htpasswd, which will look something like this...
your_username:your_encrypted_password
to a plain text file named .htpasswd in the folder you created in step W2,
W6. In the folder created in step W2, create a text file named
theusualinc.php, with this content:
<?php
$_SESSION['host'] = "HOSTNAME";
$_SESSION['user'] = "USERNAME";
$_SESSION['pswd'] = "PASSWORD";
?>
include( "/home/your_site_name/theusual/theusualinc.php" );
right below the call to session_start(), making sure that /home/your_site_name/theusual exactly matches the path to the folder you created in step W2.W8. Copy all files listed in step S1, including your newly modified copy of the_usual_start.php, into the folder you created in step W1.
W9. In your browser run http://www/your_site_name/theusual/theusual_start.php, bookmark the page, and enter your username and password.
TheUsual/PHP needs three MySQL authentication settings---$host, $user, $pswd---for authentication against the mysql.user table. These settings can be ...
If you use theusual-login.php, remember that PHP include files can be in the
php-includes path, for example in the c:/php/includes folder, or in the current
folder, but keeping such include files in the current folder is a security disaster on an
internet-visible server.
Here is a sample theusual-login.php. Fill in your own HOST,
USER and PSWD values:
<?php
$_SESSION['host'] = getenv( "u_host" ) ? getenv( "u_host" ) :
"HOST" ;
$_SESSION['user'] = getenv( "u_user" ) ? getenv( "u_user" ) :
"USER" ;
$_SESSION['pswd'] = getenv( "u_pswd" ) ? getenv( "u_pswd" ) : "PSWD" ;
?>
Versions 4.x of PHP use 3.x versions of MySQL client modules, but passwords created with MySQL since version 4.1 use an authentication protocol which earlier MySQL clients cannot decode. If you are using PHP 4.x, the password of any user of theUsual.php must have been entered with, or edited to OLD_PASSWORD( 'password' ).
Theusualcall.php is a simple frontend for selecting and running any instance of TheUsual you have access to, against any MySQL database server you have access to.
It needs a text configuration file named theusualcall.ini containing two kinds of configuration lines ...
1. For each available installation of TheUsual, one line of comma-separated key=value pairs specifying the instance's name, group, host and path:
theusual = your choice of name for this instance of TheUsual; this will be its selectable name in theusualcall.php
group = your choice of name for the group to which this instance of TheUsual belongs; installations of TheUsual with a given group name can access only MySQL database servers with the same group name
host = the LAN machine name or URL where this instance of TheUsual lives (host pingability is not verified)
path = the path at host to the file which invokes this installation of TheUsual (for example theusual_start.php)
For example, suppose you have two installations of TheUsual on your LAN ...
http://mylaptop/theusual/theusual_start.php
http://mydesktop/php/theusual/theusual_start.php
... and you also have access to a web installation of TheUsual at ...
http://www.myclientswebsite.com/theusual/mylogin.php
then theusualcall.ini needs these three lines, one for each of the above instances ...
theusual=thelaptop, group=lan, host=mylaptop, path=/theusual/theusual_start.php
theusual=thedesktop, group=lan, host=mydesktop, path=/php/theusual/theusual_start.php
theusual=myclient's site, group=myclient, host=www.myclientswebsite.com, path=/theusual/mylogin.php
2. For each available MySQL server login, one line of comma-separated key=value pairs specifying the mysql server name, its group as defined above, and optionally the username (user) and password (pswd) for that login:
mysql = the name of this MySQL server; if it is on your LAN, this is the LAN machine's name; if it is on the web, it is the MySQL server host name specified by the hosting provider
group = the name of the group to which this MySQL database server belongs; installations of TheUsual with a given group name can access only MySQL database servers with the same group name
user = the mysql.user.User value for this login; if you do not pass it, the called instance of TheUsual must specify it using another method of user/pswd authentication;
pswd = the mysql.user.Password value for this login; if you do not pass it, the called instance of TheUsual must specify it using another method of user/pswd authentication;
For the above example, theusualcall.ini would have:
mysql=mylaptop, group=lan, user=thisusername, pswd=thispassword
mysql=mydesktop, group=lan, user=anotherusername, pswd=anotherpassword
mysql=mydesktop, group=lan, user=yetanotherusername, pswd=yetanotherpassword
mysql=webprovider_name, group=myclient
where the first three lines specify logins available to either of the group=lan instances of TheUsual
defined above, and the last line tells theusualcall.php to pass only the mysql name to the instance
of TheUsual at the myclient site, and not to send user and pswd with that call (on the assumption that mylogin.php will collect and authenticate those values).
theusualcall.php ignores lines in theusualcall.ini that don't begin with 'theusual' or 'mysql'. A sample theusualcall.ini is provided.
Any number of independent instances of TheUsual can run simultaneously in browser tabs, because TheUsual implements the session setup described in Chapter 12 of Get It Done With MySQL 5&6 and under MySQL and PHP | Basics | Session setup at http://artfulsoftware.com/infotree/mysqltips.php.
On load, TheUsual offers a list of databases for which you have privileges. Once you select a database, TheUsual puts up a table selection list and a dashboard band offering custom query, database browse and other command links. Clicking on the database browse link brings up a list of tables in the current database with Analyze, Check, Optimize, Repair and Drop options.
If you make a choice from the table dropdown, you see a datagrid from that table with order-selectable headers, and a statusbar permitting selection of First/Previous/Next/Last row groups and rows-per-page selection. If the currently selected table uses an ACID-compliant storage engine like InnoDB, and if other tables in the current database have foreign keys referencing the current table, the statusbar offers a dropdown detail table selector. If you select a detail table, TheUsual displays a second grid with detail rows matching the current row of the master table.
MySQL 5 implements Views, so when run against MySQL 5 or later, theUsual/PHP lists Views as tables. To create a View, run a CREATE VIEW statement as a custom query. To run a View, select it from the Tables dropdown.
But MySQL Views have their limitations—they tend to be slow, and they disallow FROM clause subqueries, which are often needed in multi-table reports. A workaround is to save custom queries in the database, and have a point-and-click interface for selecting and executing them. TheUsual does exactly that: it can save custom queries to a saved queries table named theusualviews (in the
mysql database if privileges allow, otherwise in the current database), and it retrieves such queries for editing and execution.
Enable saved custom queries by setting $_SESSION['views']=TRUE in theusual_start.php. Then in any database you select, TheUsual creates its saved queries table if it does not exist by executing:
CREATE TABLE theusualviews(
name VARCHAR(64) NOT NULL DEFAULT '',
db VARCHAR(64) NOT NULL DEFAULT '',
User VARCHAR(16) NOT NULL DEFAULT '',
Host VARCHAR(64) NOT NULL DEFAULT '%',
qry VARCHAR(8192) NOT NULL DEFAULT '',
changed TIMESTAMP,
PRIMARY KEY(db,name)
);
and a Save button appears on the custom query form. To manage your saved queries, select theusualviews from the Tables dropdown for the appropriate database; browse and edit it as you would any other table. For convenient code editing, use the Settings panel (in the Browse database dashboard) to set text format to preformat.
As a convenience for handling longwinded SQL commands, if the query includes the text hide from theusual inside comment delimiters /* */, reproduction of the query's SQL is suppressed.
Per page: A rows/page dropdown selector appears on the dashboard when the query is pageable. Possible values are 5,10,20,50,100,500. To change these, edit $pagelens in theusual.php.
Prev, Top, Next, Last: Display the prievious, top, next or last <per page> rows returned by the current query.
Detail table: This is a dropdown selection list of ACID-compliant tables in the currently selected database with a foreign key referencing the currently selected table.
Master-detail relationships without declared foreign keys: Several MySQL storage engines offer no support for foreign keys, yet management of data in such tables often needs master-detail logic. TheUsual helps with this by letting you add, to the above child tables list, master-detail table relationships without declared foreign keys. It does this by storing such info in a table.
A table in what database? If you already have a "sys" database configured to hold general-purpose utility tables and routines, use it for this feature. If you don't have a "sys" database, and if you have privileges to create a database, we suggest you create one, then use it for this feature. If you have access to just one database, and no privileges to create other databases, you can still use these informal foreign keys by setting the database for them to the DB you are already using.
To use the feature, make sure this line ...$_SESSION['sysdb'] = 'name_of_database_to_use';
is in theusual_start.php, then before starting TheUsual, create that database.
The next time TheUsual runs, it creates a table named theusualfks in that database. You can use TheUsual (or any other MySQL client) to add rows to this table specifying master-detail (parent-child) table relationships. Here is an example. If you downloaded the database script world.sql for the sample MySQL world database from http://downloads.mysql.com/docs/world.sql.gz or http://downloads.mysql.com/docs/world.sql.zip, you may have noticed that the tables are MyISAM, not InnoDB. To make the master-detail links from the country table to the city and countrylanguage tables visible to TheUsual, use TheUsual to browse theusualfks in the database named by $_SESSION['sysdb'] and insert these two rows:
Now when you browse world.country in TheUsual, you can choose city or countrylanguage as a child table, and TheUsual will auto-generate dropdown picklists for the relevant foreign keys:
Beware that TheUsual does not (yet) validate parent-child entries in theusualfks table; it just tries to execute them as if they were real foreign keys, and reports an error if the specification is incorrect.
If the detail table itself has a detail table, the leftmost column of each detail row shows, in addition to Edit, Ins, Copy and Del options, a Go option which makes the current detail table the master table in the next browse, which will be of the page containing the selected row. Use Go to daisy-chain down any number of cascading master-detail table pairs.
If the datagrid table has a unique or primary key, there is a statusbar Find ID input box for entering a key value to search for, and every row offers options to Edit, Ins(ert), Copy or Del(ete) that row. Clicking on Edit puts the current row in edit mode, clicking on Ins brings up a new row for editing, and clicking on Copy brings up a new row which is a copy of the current row for editing. Finish an Edit, Ins or Copy cycle by clicking Save or Cancel.
Automatic foreign key lookup dropdowns: Since v1.57, during row edits, for columns that are foreign keys in ACID-compliant tables, and also for TheUsual's user-defined foreign keys, TheUsual automatically puts up a dropdown for selection of a key value from the referenced table. In that dropdown, beside the key column, it also displays a (VAR)CHAR description column, if it can find one. You can tell TheUsual what description column to use if you enabled TheUsual's user-defined foreign keys: edit the theusualfks table in the database specified by $_SESSION['sysdb'] = 'admin', and in the row for that foreign key, set the value of the column named referenced_desc_column to the desired SELECT expression (beware: TheUsual doesn't verify your syntax!).
Selecting Custom query from the dashboard brings up a custom query text control that's resizable in FireFox, Chrome and Safari, and an Execute button. If saved queries are enabled, it also has a query name control and a Save button. It supports CREATE PROCEDURE | FUNCTION | TRIGGER, for each of which, if the routine has more than one line, you should specify an alternative delimiter before, eg DELIMITER go, and after, eg END; go.
The mysql interface does not support multiple resultsets; TheUsual/mysql works around this by closing and reopening the connection for each query, but this workaround fails if the multiple queries are within a stored procedure, so with the mysql API, stored procedures that execute multiple queries will show just one resultset.
The mysqli interface does support multiple resultsets, and TheUsual/mysqli shows them all even when they're from within a stored procedure.
If you are pasting in large multi-query scripts, keep their size well within the max_post_size setting of your PHP installation, if necessary by chunking them and handing them to TheUsual one multiquery chunk at a time.
When executing multiple-query scripts, remember there's no paging, so it's best to avoid huge resultsets.
A Chart prompt appears on the dashboard if TheUsual can match the data in the current datagrid to a type of chart it knows how to draw. TheUsual can now display, on the fly, eight kinds of Google Visualisation API charts—Area, Line, Smoothed Line, Motion, Org (Tree), Pie, Pie with Percentages, and Scatter. These charts can use [VAR]CHAR, numeric and DATE values; BLOB, TEXT, ENUM and SET values are ignored. When customising queries for these charts, remember that MySQL functions like FORMAT() return strings; to make strings usable as numeric values for a chart, use CAST( FORMAT(...) AS DECIMAL[...]).
YYYYQn, or a string specifying year weeks in YYYYWnn format; and at least one numeric result column. See the example below. Here is a simple GNP-By-Continent query on the world database:
And here is an image of a minimum motion chart. All we had to do was ...
country.continent column,Motion from the Chart dropdown in TheUsual, then click the Trails checkboxes and the Play button: 
There isn't a Google Visualisation widget for histograms, but displaying a banding query as a line chart gets you the same information:
select floor(population/100000)*100000 as 'Population Band', count(*) as Size
from world.city
where countrycode='GBR'
group by 1;
Selecting Line from the Charts dropdown generates this:

Print: Version 1.44 introduced a Print option to send browsed data to the printer of your choice.
Refresh: If your most recent custom query added or dropped a database or table, use this option to refresh the Database and Table dropdown menus.
Exit: Exit.
The Browse <databasename> prompt in the dashboard brings up a view for administering all objects in the currently selected database. It includes one-click whole-database backup and options to Analyze, Check, Optimize, Repair or Drop tables. To use Browse Database as a table/column reference with Custom Query, click first on Browse Database, then on Custom Query. Your query text is preserved as you click on table names.
Settings: This form allows you to toggle text/blob formatting, stripping of HTML tags from input queries, and use of information_schema for metadata (this latter provided because the more databases and tables there are on the server, the slower information_schema is; the first information_schema access can take minutes on servers with dozens of databases and thousands of tables).
Default settings and the Settings panel:
You can change the current MySQL character set in the Settings panel. TheUsual issues matching HTML charset and PHP character-setting directives on the next page repaint. To change the default startup charset (utf8), set $_SESSION['charset'] in theusual_start.php,
Since v.1.37, the default setting of $_SESSION['use_info_schema'], which determines whether to use information_schema for metadata, is FALSE because MySQL queries on information_schema are so painfully slow when there are many databases and tables.
The default setting of $_SESSION['views'], which allows TheUsual to save queries in a database table and retrieve them for execution, is TRUE; and the default setting of $_SESSION['sysdb'], the name of the database where TheUsual will look for its table theusualfks storing data-driven non-InnoDB foreign key specifications, is sys.
To change these while TheUsual is running, click on Settings. To change the default startup settings, edit theusual_start.php. Do not specify a character with an ASCII value > 127 as a separator character.
Backup: Since v1.45, database backup is available in the database administration browser. It assembles, then offers for download, a file of SQL commands to recreate the tables, views, data, stored routines and Triggers of the current database. It writes its file to the current web folder, offers to download the file to the client, logs the file operation, and when the downlaod completes, it deletes the dump file. If the download is declined or if it fails, the file stays on the server.
Under Apache this is routine. Under Windows and IIS, it can require two additional steps: make the server folder's security tab visible, then use the Security tab to enable writes to wwwroot. Open My Computer, click on Tools | Folder Options and then on the View tab. At the bottom of the list uncheck 'Use simple file sharing (Recommended)'. Now Windows Explorer shows the Security tab in the Properties context menu for every folder. In Windows Explorer, right-click on wwwroot, select the Security tab, select the Internet Guest Account ([username]/IUSR_[username]), check Write and Modify, and press OK.
| 1.73 | Added lightweight query formatter to make CREATE VIEW results human-readable. |
| 1.72 | Corrected implementation of user's text display choice. Sort information_schema to bottom of DB list. |
| 1.71 | Corrected display of multiple resultsets from stored procedures. |
| 1.69 | Corrected handling of blank numeric values in forms. |
| 1.68 | Improved handling of missing theusualviews table. |
| 1.67 | Corrected parser code triggering warning in some foreign key checks. |
| 1.66 | Corrected handling of UNION queries. |
| 1.65 | Corrected minor error in reading user-defined foreign keys (theusualfks) table. |
| 1.64 | Corrected parsing of complex multiqueries. |
| 1.63a | Corrected typo in parentkeys(). |
| 1.63 | Removed irrelevant links in database browser. |
| 1.62 | Corrected Drop Table bug in mysql version of Browse Database. |
| 1.61 | Added automatic dropdowns for parent keys specified in theusualfks. |
| 1.60 | Automatic dropdowns and initialisation of child foreign key columns to parent key values when adding a row in detail datagrid. |
| 1.59 | Improved handling of limits in saved queries, and of missing 'sysdb' database when it has been specified. |
| 1.58 | Corrected recently introduced problem in definition of some custom query columns. |
| 1.57 | Added automatic foreign key dropdown lookups. Corrected timezone detection. |
| 1.56 | Added smoothed line charts, and pie charts with percentage display. Corrected View ordering. |
| 1.55 | Corrected handling of database-specific routine privileges for backup under shared hosting. |
| 1.54 | Corrected handling of INSERTs and UPDATEs of blank BLOB and TEXT values. |
| 1.53 | Corrected bug that prevented browse of performance_schema. |
| 1.52 | Corrected initialisation of Saved Queries dropdown. |
| 1.51 | Corrected handling of user dropping the current database. |
| 1.50 | Corrected handling of queries, Views and saved queries for charts. |
| 1.49b | Do not automatically add an ORDER BY clause to a MySQL View. |
| 1.49a | Corrected JavaScript error in Saved Query handling under IE7-8. |
| 1.49 | Does on-the-fly Google Area, Motion, Pie, Org and Scatter charts. Corrected query saving. |
| 1.48 | More key-handling workarounds for servers that still set magic_quotes_gpc. |
| 1.47 | Corrected error handlers |
| 1.46 | Cleaned up display of decimal data. Corrected saving of Saved Queries |
| 1.45 | Backup option in Browse database mode |
| 1.44 | Print option |
| 1.43 | Corrected table selection button misdisplay after browser tab restoration. 143a: removed debugging stub |
| 1.42 | Correct for character set when using column length to determine single- vs multi-line edit (mysqli) |
| 1.41 | DB Browser: Disable join to mysql.procs for routine params when user does not have that privilege |
| 1.40 | Grey out rather than omit Top Prev Next Bott buttons when they can have no effect |
| 1.39 | Added dynamic character set setting, coordinated with Set Names. Corrected column headers. |
| 1.38 | Corrected handling of escaped quotes in multiqueries |
| 1.37b | Corrected display glitches for errors, non-editable tables |
| 1.37 | Added Go option in detail browse for cascading down master-detail chains. Updated default settings. Smoothed error handling. |
| 1.36 | More text formatting options. No default ORDER BY clause in a query on a View. Corrected multi-key deletion & subquery parsing. |
| 1.35 | Added front end for multiple installations of TheUsual and of MySQL servers |
| 1.34 | Corrected master-detail synchronisation when controlling order is not the primary key |
| 1.33 | Data-driven master-detail browsing; corrections to child table argument parsing & key argument handling |
| 1.32 | Added Triggers list to database browser |
| 1.31 | Corrected handling of multiqueries and of queries with FROM clause derived tables |
| 1.30 | Improved handling of ENUMs, SETs and BOOLs in forms |
| 1.29 | Size limit setting for text and blob display/edit. Timestamp default handling improved. |
| 1.28 | Call mysql[i]_real_escape_string() for deletion key arguments only if !get_magic_quotes_gpc() |
| 1.27 | Corrected ordering of Views, handling of get_magic_quotes_gpc() |
| 1.26 | Accommodate MySQL 5-6 differences in information_schema.routines table structure |
| 1.25 | Corrected BLOB handling |
| 1.24 | Corrected handling of multi-column char keys in some update commands |
| 1.23 | Corrected handling of database and table names containing prohibited characters |
| 1.22 | Corrected handling of delimiters embedded in quoted strings inside multi-query strings |
| 1.21 | Corrected problem in Save Query |
| 1.20 | Settings form |
| 1.19 | List stored routines in database browser |
| 1.18 | Enable Drop View in database browser |
| 1.17 | Strip slashes if get_magic_quotes_gpc() is set on inserts and updates |
| 1.16 | Improved handling of MySQL commands |
| 1.15 | Database browser supports Analyze, Check, Optimize, Repair, Drop Table commands |
| 1.14 | Generalised DELIMITER support in custom queries |
| 1.13 | Support for multi-queries |
| 1.12 | Database browser |
| 1.11 | Remove any trailing semicolon from a query |
| 1.10 | Fixed row ordering glitches |
| 1.09 | Fixed master-detail glitches |
| 1.08 | Saved queries go to mysql.theusualviews if privs allow, otherwise to current db |
| 1.07 | Much faster: by default bypasses information_schema to get child table info |
| 1.06 | Instructions for installation on a shared hosting provider |
| 1.05 | Ins/Edit/Copy/Del/Save/Cancel buttons compressed. Accept NULLs to nullable columns. |
| 1.04 | Optional detail window if there is a child table |
| 1.03 | Query execution times |
| 1.02 | Support for many non-SELECT cmds |
| 1.01 | Support for calling sprocs |
| 1.00 | Original |