Objective 5: Local debugging in PHPEclipse 1.1.8 in Eclipse 3.1.2 for PHP 5.1.2 using the DBG debugger
- Observation 1: The appropriate php interpreter has to be php-cgi.exe and not php.exe
- Observation 2: The debugger generates different $_SERVER variable than otherwise anticipated. In order for my script to run properly, I needed $_SERVER["HTTP_HOST"] which was not initialized within the debugger, nor was $_SERVER["HTTP_USER_AGENT"] and while the script was anticipating something like /folder/subfolder/page.php for $_SERVER["PHP_SELF"] the debugger set PHP_SELF to something like c:\\directory\\subdir\\folder\\subfolder\\page.php. I could override HTTP_HOST and HTTP_USER_AGENT by presetting them under Environment variables prior to initiating the debugger. Presetting PHP_SELF was of no use. The only way I could override the debugger setting was by setting a breakpoint immediately after the PHP_SELF variable was accessed, and then selecting the appropriate expression under the Variables tab of the debugger, and changing its value.
Objective 6: Fix
<?=$SomeVariable?> so that it works for my online webpages.
- I tried to using the ini_set('short_open_tag', 'On') which didn't correct the problem. Turns out, according to my research, since there are cases where the remote server still won't accept the open tag format. So, I had to search and replace <?= with <?php echo_ and ?> with ; ?>.
Objective 7: Resolve and Fix
WARNING: include(../../include-folder/somefile.php) [<a href='function.include'>function.include</a>]: failed to open stream: No such file or directory in line ... followed by a string of other warning errors such as:
WARNING: include() [<a href='function.include'>function.include</a>]: Failed opening '../../includes-folder/somefile.php' for inclusion (include_path='.:/usr/local/php5/lib/php') ... .
especially annoying since the offending file seems ok.
- One reason lies in the URI containing containing more than one forward slash such as http://www.website.com//subdirectory/webpage.php. To correct, use ltrim($_SERVER['PHP_SELF'], '/') and redirect back to the rectified URI. Cautionarly Note! Make sure the redirect hasn't inadvertanttly duplicated the first subdirectory as in the example above. Redirect to the absolute and not the relative address.
- Another is the result of using <meta http-equiv="refresh" content="1;URL=gosomewhereelse.ext" /> rather than the php function header("Location: gosomewhereelse.ext"); exit(); -- NOTE! The header function has to appear before anything else is written to the file, or else you get a 'header already called' error.
Objective 8: Highlight strings not within tags
- Observation: I could not find a regular expression to easily search and replace strings not contained within anchors, or other tags. Searching the net yielded nothing other than a post at http://www.webmasterworld.com/forum88/1212.htm which gave me the idea for the HiliteSpecial ($haystack, $search, $replace=false, $tags=false) function below.
NOTE!
- $tags is used for future expansion for when search and replace within tags will be needed.
- $replace is set to false here, also for future purposes, but for now, the function call:
$excerpt=HiliteSpecial($some_string, $lookforthis, "<span class=\"tobehighlighted\">$lookforthis</span>", true); ... established the replacement I needed
-
HiliteSpecial's regular expression identifies text strings outside of any tags. The preg_match_all gathers the strings into the $strings variable.
- Observation A: Without '(int)' in it, the in_array() function didn't work as expected.
- Observation B: I read that strpos() is faster than strstr(). There is a flaw in using it in a conditional statement, however. When I used it, it failed to recognize the $search value when it in fact started from '0'. (Damn! Now I have to go back and check my other scripts.)
function HiliteSpecial ($haystack, $search, $replace=false, $tags=false) {
if ($temp=preg_match_all('/(?<=^|>)[^><]+?(?=<|$)/', $haystack, $strings) && in_array((int) $search, $strings[0]) && $tags) {
$strings=$strings[0];
foreach ($strings as $count=>$var) {
if (strstr($var, $search)) $haystack=str_replace($var, str_replace($search, $replace, $var), $haystack);
}
return $haystack;
} else return preg_replace("/$search/i", $replace, $haystack);
} // end HiliteSpecial
Objective 9: Determine what causes
Error in my_thread_global_end(): 1 threads didn't exit\r. Internet searches on what might be causing this, and how to fix it, at first seemed futile. Eventually at
PHP Bug #41350, I did find what I needed to seemingly resolve it.
(See Observation B:, below)
Developing webpages locally on my localhost, (Apache 2.2.16, php5 5.3.3-7ubuntu1) so as to emulate my remote server configuration with
SERVER API: CGI/FastCGI, I had to install and configure
mod_fcgid. After that, I experienced problems with maintaining various text-based log files. I have a special webpage for listing, viewing and processing selected logs. When I'm done, I want to remove or empty the log contents. But I had troubles doing that.
Objective 10: To be able to write, overwrite or remove log files without generating
fopen(logs/somefile.log): failed to open stream: Permission denied ... errors.
- Observation A:
- Rather than deleting a problem free file by using unlink($file), just emptying the contents preserved the integrity of the file. This prevented the server from later creating a new 'protected' file I might not be able to access and append text to.
- Using AddHandler fcgid-script .php in my .htaccess files, I experienced various unexplainable problems with fopen() and fwrite() functions.
- chmod($file,0755), chown($file,'owner') and chgrp($file,'group') generated errors, or didn't solve the problem.
- I wrote a function that, before loading any webpage, would successfully empty the log contents of any and all files listed in an array. An echo statement showed file_exists($file) && is_writable($file) to be true for each file. HOWEVER, for some strange reason, when I tried to alter the script so as to work successfully for one specific file, file_exists($file) && !is_writable($file) was true!
Below are some interesting things I failed to find through tons of google searches and the hundreds of solutions proposed.
- Solutions: Here are some of the ways I overcame the issues above. But beware! I tried all kinds of ways to skirt or overcome the problems. If my solutions are incorrect, I apologize. Perhaps I misled myself into thinking I found the answers.
- Solution A: To get files to be writable, if your using fcgid, which I am, or FastCGI, Options +ExecCGI might already be set in your Virtual Host definition file, but if you're using .htaccess, your Options should also include +ExecCGI.
- Solution B1: If you're using mod_fcgid, your Virtual Host definition file should include something along the lines of the below
<IfModule mod_fcgid.c>
# if not set correctly, the following line can screw up php's access to created files/logs
SuexecUserGroup owner group
<Directory /path/to/root_directory/>
Options +ExecCGI +FollowSymLinks -Indexes
AllowOverride All
AddHandler fcgid-script .php
FCGIWrapper /var/www/php-fcgi-scripts/legacies/php-fcgi-starter .php
Order allow,deny
Allow from all
</Directory>
</IfModule>
- Solution B2: With regards to trying to reset a newly created file's permission level, owner and group settings, I found that the exampe below worked. Solutions I found on the net, didn't clarify that the file resource must first be opened before it's settings can be changed.
if (!file_exists($file) && !$ThisCondition) @touch($file, time());
if (file_exists($file) && is_writable($file)) {
$mode=(($ThisCondition)? "w": "a+b");
fwrite($handle, $mode);
chmod($file,0755);
chown($file,'owner');
chgrp($file,'group');
fclose($handle);
clearstatcache();
}