in8notes

This portion of my site is powered by Blosxom. Blosxom is a perl script whose functionality here is extended through several plugin scripts in order to dynamically assemble a multitude of separate plain text files stored in a directory tree on the server into a cohesive, dated and RSS enabled weblog. Now in daily (r)sync with the directories on Nate's Powerbook.


home / computers / code



blosxom
categorytree plugin
blox plugin
find plugin
breadcrumbs plugin



       
Return to in8sworld.net


Tidying up

from
http://www.ibm.com/developerworks/library/x-tiptidy.html

Obviously, the first step is to download and install HTML Tidy (which you'll find in Resources). HTML Tidy is available on most platforms, including Windows, Linux, and MacOS. The default executable is a command-line tool, but GUI versions are available for Windows and MacOS.

To run HTML Tidy, open a terminal and issue the following command:

tidy -asxhtml -numeric < index.html > index.xml

That's it! HTML Tidy immediately converts index.html into index.xml. HTML Tidy will print messages that highlight issues with the original HTML document during the conversion. In most cases, you can safely ignore these messages.

HTML Tidy runs as a filter, so it expects standard input and it prints the result to the standard output. The redirection operators (< and >) allow you to work with files. By default, HTML Tidy produces a clean HTML page, but you can set two options to output XML, instead:

* -asxhtml outputs XHTML documents instead of HTML.
* -numeric uses character entities instead of HTML entities. For example, î is replaced with î.

Last saved: 08/23/2008
Links: /computers/code / xml-tidy.txt

Mediawiki settings I keep losing

from http://meta.wikimedia.org/wiki/Anti-spam_Features

If you want to create a "gated community" where new users can't even register without asking you to set up an account for them, add the following to your LocalSettings.php:

#Disallow creating accounts
$wgGroupPermissions['*']['createaccount'] = false;

Last saved: 09/09/2007
Links: /computers/code / wiki-settings.txt

Oracle -> CSV -> Excel

from http://srmwww.gov.bc.ca/gis/dbf2ora.html

1. Export the Oracle table as a .csv file, using sqlplus commands. Here's an example:

spool species.csv
set termout off
set pagesize 0
set heading off
set feedback off
select species||','||count||','|| rating from species_ratings;
quit

2. Transfer the .csv file from the Oracle server (usually HP Unix) to your Excel platform (PC or Mac).
3. Open the CSV file as an Excel spreadsheet.

Last saved: 11/25/2005
Links: /computers/code / oracle-csv.txt

php oracle extension

This page describes using the oci8 extension to connect to an oracle database. It does say that I will need the oracle client libraries for it to function. I think those are free from Oracle (or I can get them free since I have an oracle support contract)

http://www.phpbuilder.com/manual/ref.oci8.php

I jumped onto Oracle and downloaded both the OCCI package which I think are the libraries you need in order to build C programs which connect to Oracle, and then the Oracle instant client 10.1 which was updated in March. I tried this once before (in Novemeber) but never got very far. I assume I'll have to set up the php-oci8 or php-oracle extension to get this to work and that would now be possible since I figured out how to enable php-odbc already (I think)

To install php-oci8-4.3.9-2.2.el4.i386.rpm, I have a dependancy problem: libclntsh.so.10.1 which is in the instant-client bundle, so that much makes sense. I found the path to the client libraries: /usr/lib/oracle/10.1.0.3/client/lib and copied all the newer client libraries in there. Next is to ensure they are in the path. I think it will need to be accessible to the apache user as well. According to reading I've done "... installing the instant client rpms and setting the LD_LIBRARY_PATH should be all which is needed." I ended up putting a couple lines in /etc/profile:

LD_LIBRARY_PATH="/usr/lib/oracle/10.1.0.3/client/lib"
export LD_LIBRARY_PATH

which gets the variable set for everyone. For some reason this did not make the variable accessible to root, so I had to add it to root's ~/.bashrc file directly. It still wouldn't install but that was because I didn't install the 'instant client' (heh...) through rpm so it didn't know the files were there. I installed using the --nodeps switch and have to move the files to the right places like I did with php-odbc:

etc/php.d/oci8.ini ---> /etc/php
/usr/lib/php4/oci8.so ---> /usr/lib/php/extensions

Well, it appears I may need to recompile php to get it to work with oci8. The configure command (given by phpinfo()) shows that the argument -with-oci8 wasn't used:

'./configure' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib' '--libexecdir=/usr/lib' '--localstatedir=/var/lib' '--sharedstatedir=/usr/com' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--enable-discard-path' '--disable-force-cgi-redirect' '--enable-shared' '--disable-static' '--disable-debug' '--disable-rpath' '--enable-pic' '--enable-inline-optimization' '--enable-memory-limit' '--with-config-file-path=/etc' '--with-config-file-scan-dir=/etc/php' '--with-pear=/usr/share/pear' '--enable-magic-quotes' '--enable-debugger' '--enable-track-vars' '--with-exec-dir=/usr/bin' '--with-versioning' '--with-mod_charset' '--with-regex=php' '--enable-track-vars' '--enable-trans-sid' '--enable-safe-mode' '--enable-ctype' '--enable-ftp' '--with-gettext=/usr' '--enable-posix' '--enable-session' '--enable-sysvsem' '--enable-sysvshm' '--enable-yp' '--with-openssl=/usr' '--without-kerberos' '--with-ttf' '--with-freetype-dir=/usr' '--with-zlib=/usr' '--with-zlib=/usr' '--with-zlib-dir=/usr'

According to this page:
http://www-portal-stage.oracle.com/technology/pub/notes/technote_php_instant.html
I may need to patch php since the version I'm on has a bug :(. Perhaps upgrading is an easier idea? It's supposed to be fixed in 4.3.11? I'm on 4.3.3. From php.net: "...If you're using Oracle Instant Client, you need to build PHP with the option --with-oci8-instant-clientDIR. Note that Oracle Instant Client support first appeared in versions 4.3.11 and 5.0.4."

Last saved: 06/19/2005
Links: /computers/code / php-oracle.txt

ODBC on Linux

Looking for a way to connect my Mandrake (now Mandriva) Linux webserver to a remote Redhat ES2.1/Oracle box in order to possibly build dynamic web pages using the data thereon, I found a php-odbc package (unixODBC) for Redhat with two files in it: odbc.ini and odbc.so. Restarting apache didn't make odbc appear in phpinfo(), but as soon as I copied the files where mandrake wanted them, edited the /etc/php.ini file to enable the external module odbc, and restarted it did appear. I thought i was on the right track.
odbc.so needs to go in /usr/lib/php/extensions
odbc.ini needs to go in etc/php

Then I thought I needed to set up the system DSN files to point to the other machine. Really simple instructions here:
http://www.unixodbc.org/odbcinst.html
I haven't done that yet.

Then it got confusing again. According to Zend (php), I might need iODBC. "ODBC connections involve an application, driver manager, driver, and database." iODBC is a driver manager (like the ODBC Control Panel applet in Windows). According to wikipedia, unixODBC is also a driver manager thats used by OpenOffice, while iODBC is the manager used by MacOSX.
http://www.zend.com/zend/tut/odbc.php
How to configure iODBC is here:
http://www.iodbc.org/index.php?page=languages/php/odbc-phpHOWTO

In either case, I seem to still need a driver.
Yikes, easysoft offers a free 30 day trial download of their drivers for Oracle which is nice but it seems that it'll be $1,600 to use them after that! I'm afraid that will not fly.

I may be barking up the wrong tree here - since php has oracle functions built in. I may just need a different extension.

Last saved: 06/19/2005
Links: /computers/code / php-odbc.txt

Recursive Directory listing

# function displaydir ($path, $depth) {
if (($d = @opendir ($path)) === false) echo ('[Could not open path:]');
else {
while ($f = readdir ($d)) {
if ($f != "." && $f != "..") {
if (is_dir ($path . "/" . $f)) {
for ($i = 0; $i < $depth - 1; $i++) echo '| ';
echo '+-';
echo "$f\n";
$depth++;
displaydir ($path . "/" . $f, $depth);
$depth--;
} else {
if ($sf == 1) {
for ($i = 0; $i < $depth - 1; $i++) echo '| ';
echo '+-';
echo "$f\n";
}
}
}
}
closedir ($d);
}
}

displaydir ($url, 0);
?>

Last saved: 06/17/2005
Links: /computers/code / php-recursive-dir.txt

Recursive PHP directory listing

# $path = "./";

if (strrpos($moverse,'..')) {
$moverse = str_replace('/..','',$moverse);
$moverse = substr($moverse,0,strrpos($moverse,'/'));
}

if (strpos($moverse,'..')===false) { // php is weakly typed
} else if (strpos($moverse,'..')==0) {
echo 'Bad Hacker = No caffeine';
$moverse="";
}

if($moverse) {
$moverse = $moverse."/";
if (strpos($moverse,"\'")) { // This corrects a uri that includes single quote(s), which I think gets messed up by GET
$moverse = str_replace("\'","'",$moverse);
}
}

echo $moverse."
"."\n";

$handle=opendir($path.$moverse);

while ($file = readdir($handle)) {
if(is_dir($path.$moverse.$file) && $file != ".") {
if ($file == ".." && $moverse == "") {

} else {
$uri=str_replace(" ","%20",$moverse.$file);
echo ''.$file.'
'."\n";
}
} else if ($file != "." && $file != "index.php") {
$uri=str_replace(" ","%20",$path.$moverse.$file);
echo ''.$file.'
'."\n";
}
}
?>

Last saved: 06/17/2005
Links: /computers/code / php-recursive-dir2.txt

Uptime function

  • Nate's very first phpblock to display the machine uptime
  • The original code was shamelessly scammed off the internet,
  • but has been modified to display days and hours only.
  • March 8, 2005
    **/
    function phpblock_uptime() {
$uptime_array = explode(" ", exec("cat /proc/uptime"));
$seconds = round($uptime_array[0], 0);
$minutes = $seconds / 60;
$hours = $minutes / 60;
$days = floor($hours / 24);
$hours = floor($hours - ($days * 24));
$minutes = floor($minutes - ($days * 24 * 60) - ($hours * 60));
$seconds = floor($seconds - ($days * 24 * 60 * 60) - ($hours * 60 * 60) - ($minutes * 60));
$uptime_array = array($days, $hours, $minutes, $seconds);

global $_RIGHTS, $_CST_VERBOSE;
$retval = '';
return $retval .= $uptime_array[0] . ' day(s), ' . $uptime_array[1] . ' hour(s) ';

}

Last saved: 03/19/2005
Links: /computers/code / uptime.txt

Connect to remote Oracel database with php

$db ="(DESCRIPTION =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = spt-cidb)
(PORT = 1521)
)
(CONNECT_DATA = (SID = cidb))
)";

$odbc = ocilogon ('store', 'mypass', $db) or die( "Could not connect to Oracle database!") or die (ocierror());
var_dump($odbc);

Last saved: 03/17/2005
Links: /computers/code / php-remote2oracle.txt

PHP FTP Recursive Put and Remove/Delete files

The following functions will recursively put (ftp_putAll()) and remove(ftp_rmAll()) files through FTP. This feature is much needed in PHP, yet it was very hard to scrounge these two functions together. I found the majority of the code for them on PHP?s comments pages, however in the form that they were in at the time, neither of them worked as expected. I also put comments in the functions so that they make more sense. Read on for the code.

// This nifty function recursively removes all files in a certain directory through FTP
// NOTE: use full path name for the destination directory
function ftp_rmAll($conn_id,$dst_dir){
$ar_files = ftp_nlist($conn_id, $dst_dir);
if (is_array($ar_files)){ // makes sure there are files
for ($i=0;$i $st_file = $ar_files[$i];
if (ftp_size($conn_id, $st_file) == -1){ // check if it is a directory
ftp_rmAll($conn_id, $st_file); // if so, use recursion
} else {
ftp_delete($conn_id, $st_file); // if not, delete the file
}
}
}
ftp_rmdir($conn_id, $dst_dir); // delete empty directories
}

// This nifty function recursively puts all files in a certain directory to a server through FTP
// NOTE: use full path name for the destination directory and the destination directory must already exist
function ftp_putAll($conn_id, $src_dir, $dst_dir) {
$d = dir($src_dir);
while($file = $d->read()) { // do this for each file in the directory
if ($file != ?.? && $file != ?..?) { // to prevent an infinite loop
if (is_dir($src_dir.??.$file)) { / do the following if it is a directory
if (!@ftp_chdir($conn_id, $dst_dir.?/?.$file)) {
ftp_mkdir($conn_id, $dst_dir.??.$file); / create directories that do not yet exist
}
ftp_putAll($conn_id, $src_dir.??.$file, $dst_dir.??.$file); // recursive part
} else {
$upload = ftp_put($conn_id, $dst_dir.??.$file, $src_dir.??.$file, FTP_BINARY); // put the files
}
}
}
$d->close();
}
?>

Last saved: 03/15/2005
Links: /computers/code / php-recursive-ftp.txt

php file_exists should do what I need

if ( file_exists('/home/user/public_html/includes/config.php') )
{
include('includes/config.php');

or this

$filename = '/path/to/foo.txt';

if (file_exists($filename)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
?>

or this

/**
*Check if a file exists in the include path
*
*@version 1.2.0
*@author Aidan Lister *@param string $file Name of the file to look for
*@return bool TRUE if the file exists, FALSE if it does not
*/
function file_exists_incpath($file)
{
$paths=explode(PATH_SEPARATOR, get_include_path());

foreach($paths as $path) {
// Formulate the absolute path
$fullpath = $path . DIRECTORY_SEPARATOR . $file;

// Check it
if (file_exists($fullpath)) {
return true;
}
}

return $fullpath;
}

?>

Last saved: 03/15/2005
Links: /computers/code / php-file_exists.txt

function Truncate

/*

  • string Truncate ( string str , int length)
  • @param string str string to truncate /abbreviate
  • @param int length length to truncate /abbreviate to
  • @param string traling string to use for trailing on truncated strings
  • @return string abbreviated string
    */

function Truncate ($str, $length=10, $trailing='...')
{
// take off chars for the trailing
$length-=strlen($trailing);
if (strlen($str) > $length)
{
// string exceeded length, truncate and add trailing dots
return substr($str,0,$length).$trailing;
}
else
{
// string was already short enough, return the string
$res = $str;
}

return $res;
}

Last saved: 03/13/2005
Links: /computers/code / php-truncate.txt

Regular Expressions - Validating Email Addresses

from http://www.php-scripts.com/php_diary/122999.php3

Yesterday during the wee hours I added a mail list to my form and today I'm going to go through how I did it. The first thing you need to do is determine if the email you are dealing with is in the valid format or not. Validating email addresses isn't a perfect science, unfortunately. When you think of all the different possible formats, you have to be pretty broad -- maybe too broad -- in defining a matching pattern (or regular expression, whatever you prefer to call it). You will find many different regular expressions other programmers have written for validating email addresses so mine certainly isn't the only one (nor am I egotistical enough to suggest it is the best one), but it is one that works:

// join the mail list?
if ($php_script_list == "yes")
{
// is the $from email address in valid format?
if(ereg("([[:alnum:]\.\-]+)(\@[[:alnum:]\.\-]+\.+)", $from))

First we make sure the $php_script_list checkbox is checked. Then we check the syntax of the user submitted $from email address. The first portion of the email needs to contain at least one but likely more {alnum} alphanumeric (a-z or 0-9) character or the dash - symbol then there must be the @ symbol followed by at least one, but likely more. Then there is more alphanumeric characters and at least one period mixed in there. That's what that long somewhat cryptic regular expression means.

abc@123.com would be a valid email
abc@123com woud be an INvalid email (missing period)
1-1@1-1.com would be a valid email
1-2.com would be an INvalid email (missing @)

In regular expressions you enclose ranges within brackets. Thus [a-z] would mean any letter between a-z would return true. [a-c] would only return true if a,b,c was in the comparison string. I encourage you to refer to the php manual and look at the ereg function again.Note that when using ereg function patterns are case sensitive.

int ereg(string pattern, string string, array [regs]);

Use the eregi function in place of ereg for patterns that are case INsensitive. Let's look at the rest of the mail list code:

if(file_exists("email_list.txt"))
{
$newfile = fopen("email_list.txt", "r");
while(!feof($newfile))
{
$duplicate = fgetss($newfile, 255);
// is email address submitted already on file?
if(eregi("$from", $duplicate))
{
print("This email $from");
print(" is already in the database.
Please go back");
print(" and uncheck the mail list box");
fclose($newfile);
exit;
}
}
fclose($newfile);
$addemail = fopen("email_list.txt", "a");
fputs($addemail, "$from\n");
fclose($addemail);
}
else
{
// since file doesn't already exist, let's create for first time
$newfile = fopen("email_list.txt", "a");
fputs($newfile, "$from\n");
fclose($newfile);
chmod("email_list.txt", 0666);
}

Start by determining whether the email_list.txt file exists. If it does not exist then this is the very first time someone is being added to the list and we don't need to bother with checking to see whether their email address is in the list or not. So we only need to create the file and write the email address. You may also notice I used the chmod function to set the file permissions for the email_list.txt file. This line of code is optional. When using the "a"ppend file option, Unix will automatically create the file for the first time and set the permissions. The problem is, depending, on the directory and umask settings it may create a file that only the script has owner permissions to read and write and update. By using the chmod function sometimes can be the only way to gain the permissions you want once a script has set the initial permissions. If you try to FTP a file to a directory and get the "permissions denied" error, you may very well need to write a small PHP script using the chmod command to change the permissions of the file (or simply delete the file, but then you'll lose the data in it). Ok, but let's say the email_list.txt file does exist, now the most logical thing to do is make sure we don't already have that same email address on file.  We do this by reading a line at a time of the existing file and comparing that line (I named the variable $duplicate) against the $from email address and seeing if there is a match.  If there is then we print the message to the browser letting the person submitting the form know that we already have that email address in the database, close the open file, and exit the script. They can go back and uncheck the box and resubmit and the email will go through fine. Now if the email address does not match another email in the database they are appended to the end of the database.

Changing a strings case in PHP

Want to force text in a string to be all capital or lowercase letters? You could do this the long way using regular expressions, but PHP has several cool built-in functions for this.

// force all uppercase
print(strtoupper("i bet this will show up as all letters capitalized
"));
// force all lowercase
print(strtolower("I BET THIS WILL SHOW UP AS ALL LETTERS IN LOWERCASE
"));
// force the first letter of a string to be capitalized
print(ucfirst("i bet this will show the first letter of the string capitalized
"));
// force the first letter of each WORD in a string to be capitalized
print(ucwords("i bet this will show the first letter of every word capitalized
"));
?>

Last saved: 03/13/2005
Links: /computers/code / php-regularexpressions.txt

To search for some specific file or file extension:

Make sure that you put this expression
if (ereg("\.sql",$file)) instead of (eregi(".sql",$file)) since the ereg function is familiar with regular expressions
and "the point" (any char) represents a special reg expr. (have a look at reg expr. if you are interested!)

You can combine in the if expression whatever you want for instance if (ereg("\.sql",$file)) && (strlen($file))<100 )
:) of course this doesn't make sooo much sense to use a strlen here, but however this should only be a demonstration

Now the next thing...
Speed issue :
Since the ereg() is capable of reg expr. this means a high speed decrease for you.
So for this simple fileextension search function use the strstr() function instead... which hasn't the power of reg expr. but boast of speed
At least your "if expression" should look something like that: if(stristr($file,".sql"))

Whilst writing a script to check a directory to see whether certain files existed,
I used an original example from this page and modified so that in the first loop
that checks the directory, there is a second that looks at a database recordset
and tries to find the matches.

I found an issue that I have not yet solved. I am not a PHP guru, so I might be
missing something here.

In the parent loop, $file is set correctly. As soon as your progress to the inner
loop, $file becomes just a full stop (.) - I've no idea why.

if ($handle = opendir($path)) :
while (false !== ($file = readdir($handle))) :
// Here $file is set correctly
while($row = @ mysql_fetch_array($result)) :
// Here $file is set to .

endwhile;
endwhile;
  
closedir($handle);
endif;
?>

Last saved: 03/13/2005
Links: /computers/code / php-findfile.txt

php List Dir function
function list_directory($dir) {
$file_list = '';
$stack[] = $dir;
while ($stack) {
$current_dir = array_pop($stack);
if ($dh = opendir($current_dir)) {
while (($file = readdir($dh)) !== false) {
if ($file !== '.' AND $file !== '..') {
$current_file = "{$current_dir}/{$file}";
if (is_file($current_file)) {
$file_list[] = "{$current_dir}/{$file}";
} elseif (is_dir($current_file)) {
$stack[] = $current_file;
}
}
}
}
}
return $file_list;
}
?>

Last saved: 03/13/2005
Links: /computers/code / php-list-dir.txt

php readdir()
if ($handle = opendir('.')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
echo "$file\n";
}
}
closedir($handle);
}
?>

Last saved: 03/13/2005
Links: /computers/code / php-read-dir.txt

Apache mod_rewrite

I'm told that i can use this to alter apache's handling of the bloxsom.cgi so that it will allow it to appear at the "root URL" of the domain. This is not critical to me, but would be nice to know how to do: RewriteEngine On
#Any other paths you don't want handled by blosxom.cgi
#setup like the "/images" directory
RewriteRule ^images - [L]
RewriteRule ^(.*) /cgi-bin/blosxom.cgi$1 [PT]

another guy has this:

RewriteRule ^$ /cgi-bin/blosxom.cgi
RewriteRule ^/$ /cgi-bin/blosxom.cgi

another post says that instead of:

RewriteRule ^weblog [target]
do
RewriteRule ^weblog$ [target]
RewriteRule ^weblog/(.*)$ [target]/$1

all about rewrites here: http://httpd.apache.org/docs-2.0/mod/mod_rewrite.html

The meat of the matter is here:

Text:
. Any single character
[chars] Character class: One of chars
[^chars] Character class: None of chars
text1|text2 Alternative: text1 or text2

Quantifiers:
? 0 or 1 of the preceding text
* 0 or N of the preceding text (N > 0)
+ 1 or N of the preceding text (N > 1)

Grouping:
(text) Grouping of text
(either to set the borders of an alternative or
for making backreferences where the Nth group can
be used on the RHS of a RewriteRule with $N)

Anchors:
^ Start of line anchor
$ End of line anchor

Escaping:
\char escape that particular char
(for instance to specify the chars ".[]()" etc.)

Last saved: 03/01/2005
Links: /computers/code / apacheModRewrite.txt