Find what week of the month a date is in PHP

{EAV_BLOG_VER:cf05756ccfd5297d}

The need for this routine comes up every now and then and it confuses people because they thing date(“W”) will do the trick.

Once they realize that’s the week of the year, they start to get all elaborate in finding ways to get which week in the month it is.

Applying a little logic, you can come up with the simple solution of subtracting away all of the weeks before the start of the month an the remainder is your answer

 

Like so:

$weekNum = date(“W”) – date(“W”, strtotime(date(“Y-m-01”, now()))) + 1;

(Drop the + 1 if you want it to be zero based.

HOW TO: Take a quick glance at errors from a project.

PHP records all errors to a file named error_log

I needed to look at the status of a project on two servers to see what errors were being thrown.

This command line shows the top 20 errors and how often they occurred within the last 1000 errors..
tail -1000 error_log | awk -F ‘]’ ‘{print $4}’| sort | uniq -c | sort -nr | head -20

Depending upon the load on your server, that could report on the errors in the last half hour, or across several days. In either case, it will give you a quick idea on where you should clean your code of warnings and notices and where you need to do some fixing… Just remember there’s no time line involved in the report. So the error messages could be from something already fixed.

What is CGI and What is FastCGI?

There was a long rant in the wp-testers mailing list today talking about how we weren’t helpful to someone who was getting a “500 Internal Server Error” message after installing WordPress.  After complaining about our helpfulness and some bragging about past income levels, the poster said:

Quickly about the Internal Server Error.  It most probably has to do with using fast graphics on a server.  Older version of Apache like 1.333 are still in use with major hosting sites.  Using fast graphics with this slopped together code from wordpress will quite often cause  500 errors by causing the server to time out on you.

I think the writer misunderstood the meaning of FastCGI.  I wrote this reply/post to help clarify it for him and for myself as well:

We old school programmers remember the term CGI as “Computer Graphics Interface” and how it related to the initial concepts that matured into the video card drivers supplied with Windows. In DOS, the games you ran each came with their own hand written drivers for the most popular cards. CGI was a standard for writing these drivers. I still have a CGI programming book on my shelf that talks about programming for the Trident, Matrox and Tseng Labs video cards. As a side note, CGI in the movie industry refers to Computer Generated Images – also graphics related.

But when talking about Web Servers, CGI is the Common Gateway Interface. It really has little or nothing to do with graphics. The CGI is basically how the server turns website requests into the execution of console programs and the passing of the results back to the browser. In my experience, straight CGI programming is most often done in PERL, but doesn’t have to be. CGI programs are separate and independent from the Apache server. They are executed and return a result. That’s it.

FastCGI is an extended version of the CGI that is optimized for speed and scalability. It has also been extended to allow the web server to run on one machine and the CGI calls to execute on another.

Where all this comes into play with PHP (and WordPress) is that PHP can be connected with Apache (or lighttpd or w/e) in different ways. It can be a module interfacing through Apache API calls. Or it could also be a CGI application. If connected to Apache via CGI, the PHP code is executed by the server as console calls to a separate PHP application. Since FastCGI is compatible with CGI, FastCGI can also be a chosen interface between PHP and Apache or whatever webserver you are using.

As all of this changes how PHP and your webserver talk, over the years there have been bugs in WP that were specific to FastCGI servers. However, a 500 Internal Server Error is simply the server saying “OK This is all screwed up and I have no idea what to do now.”. Yeah, maybe that has something to do with how FastCGI is setup, but it is even more likely that you are simply missing a bracket or comma in your .htaccess file.

So even if this question had been in the right forum, we couldn’t have helped the person.  When the question is ‘My server says “Something is screwed up”. How do I fix it?’, the best response we can offer will start with  “Ummmmm”.

Also, I’ve come to understand this stuff just through passing conversations with SysAdmins and random reading. So please correct me if I am wrong on any of this.

How do you get the current directory name in PHP?

I ran into a situation where I wanted to get the name of the directory I was in, in PHP. To be clear, I didn’t want the full path, just the directory/folder name

To be clear, if I was working in the directory:
/home/username/public_html/addonname

I wanted to have addonname returned.

I worked out two solutions.

The first solution used the getcwd() function which returns the full directory path as shown above but to use the basename function to get the part I needed. It worked so… “echo basename(getcwd());” returns “addonname” in this scenario.

That would meet my needs perfectly. I believe that matches my requirements in spirit, but was not literally correct. That statement returned the current working directory, but not the directory where the file was located. In fact, PHP 4 and PHP 5 differ when getcwd() is called from the command line. If you are in the ‘/’ directory and execute “php /test/talktome.php“, a php 4 getcwd() in that file will return the path “/test” while PHP 5 will correctly return ‘/’.

To resolve this, this next call works even better:
echo basename(dirname(__FILE__));

Does anyone want to do some speed tests to see which is faster after 10,000 calls? Let us know your results.

WordPress Quick Tip: Fixing the number of comments per post

For various reasons, sometimes the number of comments shown under the title of the post may not match the number of actual comments displayed under the post.

Here is a simple SQL statement that will resolve the issue:

update `wp_posts` set comment_count = (select count(*) from wp_comments 
WHERE `comment_post_ID` = `ID` and comment_approved = '1')

You can use this to verify what would change and where your problems may lie:

SELECT ID, `post_title`, `comment_count`, 
    (select count(*) from `wp_comments` 
        WHERE (`comment_post_ID` = `ID`) and (`comment_approved` = '1')) as NewCC 
    FROM `wp_posts` 
    WHERE `comment_count` <> (select count(*) from `wp_comments` 
        WHERE (`comment_post_ID` = `ID`) and (`comment_approved` = '1'))

PHPMyAdmin announces drop of PHP 4 support.

I was just over at the PHPMyAdmin site and saw this quote:

 Welcome to phpMyAdmin 2.11, which will probably be the last series supporting PHP 4.

Notice the “probably” stuck in there.  They are testing the waters.

If phpMyAdmin is dropping the whole PHP 4 line, it just might push the WordPress adoption time a bit further.  Where phpMyAdmin goes, I have to think,  the ISPs will not be slow to follow.

How to have a central VCL for PHP location for all your websites

I have a number of sites that on which I want to use the VCL for PHP library components with Delphi for PHP creations.  I don’t want to waste uneeded space for a bazillion copies of the VCL.  As far as that goes, I don’t want to have to sit through the deployment wizard every time either.

You could edit PHP.ini and add the location to your include path, but the VCL for PHP is MORE than just a textual code libary.  It includes image files as well, for things like the dropdown arrow in the combo boxes.

 So what’s a person to do?  Well, it’s simple.  Create some symbolic links!

Just put the VCL in your root directory or at least one that can be accessed with a common path from the your website directories.  I use the root since I can use ~ to get at it easily on Linux.  It could just as easily be /usr/local/lib/vcl or d:\VCL.  Then in your directories you just put two symbolic links, one named vcl and the other named vcl-bin. Both pointing to the vcl directory you made.

Here’s the step by step for *nix systems:

  1. Upload the whole VCL folder to the root web directory
  2. Telnet/ssh into the account
  3. Change to the directory for your website
  4. Run these two commands
    1. ln ~/vcl
    2. ln ~/vcl vcl-bin
  5. Repeat steps 3 and 4 for all of your sites.
  6. When you deploy, just grab the files in your project directory and upload them.  No worrying about the VCL any more.  You should be able to make a batch file that does that step!

That’s it (oh and just in case your font makes “ln” hard to readand that is a lower case “LN” as in link.)

 On Windows, you should be able to do the same thing.  If you have Vista you have native support for symbolic links.  And in XP, you can use NTFS links.  But I’ll leave it up to you to look up those technologies.  With that sort of thing, if you aren’t able to find and digest how to do it, you’re probably better off just using the deploy tool.

 Hope this helps someone!  It’s made my life a little easier.

Windows Implementation

Kevin Berry came up with this windows implementation:

For my Windows 2000 webserver, which I have total acces to, below is how I followed Brian Layman’s advice to made this work.

1. Downloaded linkmagic.exe from
http://users.pandora.be/jbranders/linkmagic.exe

2. Ran linkmagic.exe (setup program) on my webserver.

3. Launched Junction Link Magic program.

4. Created empty “vcl” folder in my clock project folder in my webserver root (c:\web\htdocs\clock\vcl) and selected this vcl folder as my junction folder.

5. Selected my true vcl folder loaded with vcl files as my destination folder (c:\web\vcl)

6. Clicked “create” button

Now my D4PHP clock sample program runs just fine in c:\web\htdocs\clock with only one main vcl installation on my webserver.

I suppose I could use the Junction Link Magic program to create new vcl junction folders in other vcl project subfolders on my webserver, but I discovered that once the first vcl junction folder is created, I can create more of these just by copying an existing vcl junction folder into a new project folder and choosing cancel when the file overwrite prompt appears. If I delete a vcl junction point folder, the real folder and its files don’t get deleted.

I for one don’t want different versions of my vcl all over my webserver in different folders (assuming I’ll have lots of web projects someday). For me it’s just simplest knowing the latest and greatest vcl library is always in one spot on my web server.

I don’t know if one could duplicate the directory structure of a windows hosted web from a remote server on one’s own computer to create the junction folder and then ftp that junction folder out to the remote server and preserve the redirection. If so, that would be great.

For my webserver, this is pretty nifty, Thanks again to Brian for the workaround until Codegear/Qadram figure out what I hope to be a better vcl deployment method.

Alternative Solution

David Plock also suggested another methot that uses a VCL-BIN alias. Jose Leon Serna provided the final fix to get this working. Kevin has done a great job of writing up these steps as well:

Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all

3. In my php.ini file I added the following so that php will know in which folder to find the vcl folder.

include_path = “.;c:\web”

If I had dropped my vcl folder into my root directory on my webserver, the entry would have been:

include_path = “.;c:\web\htdocs”

4. Jose added the final piece to make this work. In my vcl.inc.php file I modified a line so that the alias name gets passed properly to my webserver. The line that mentions vcl-bin needs a forward slash in front of vcl-bin so the final line appears like this:

if (!array_key_exists(‘FOR_PREVIEW’,$_SERVER)) $http_path=’/vcl-bin’;

5. Make sure all configuration file changes above are saved and then restart the webserver.

Now you can drop D4PHP projects in any subfolders or even subfolders of subfolders of your root directory on your webserver and they work.

The nice thing about this solution in addition to it being a single vcl deployment is that it seems to me any web hoster can implement it once for
the entire web server and any subscribers can simply ftp D4PHP web files to their own folders on the server and they’ll work.

Thanks Brian, David, and Jose for two ways to make a single vcl deployment work!!!

If you want to see this solution in action, you can visit these links (on my slow webserver) for as long as my internet service provider leaves my ip address alone. The vcl folder is outside the web root and only clock.php, clock.xml.php, and background.gif are in each of these folders.

http://24.2.90.16/clock.php
http://24.2.90.16/clock/clock.php
http://24.2.90.16/clock/clock/clock.php
http://24.2.90.16/clock/clock/clock/clock.php

There you are. Two different methods proven successful in the field! Enjoy!