2

I have a log method which saves to a file that is named the same as the script calling it, only with a capital first letter, which works sometimes, but other times capitalizes the second letter (I can't see any pattern as to when it does what but it's always consistent, meaning that file A will always either be initial capped or second letter capped, it's not arbitrary).

Here's my code...

function logData($str){
    $filePath = $_SERVER["SCRIPT_FILENAME"]; 

    $dir = substr($filePath, 0, strrpos($filePath, "/") + 1);   
    $fileName = substr($filePath,strrpos($filePath, "/")+1);
    $fileName = preg_replace('/\w+$/','log',$fileName);
    $fileName = ucfirst($fileName);  
    $fHandle = fopen( $dir.$fileName , "a");
    $contents = fwrite($fHandle, $str ."\n");
    fclose($fHandle);
}

Does anyone have any thoughts on what could be causing such an odd behavior *some of the time?

I know I can brute force it with a strtoupper on the first char and then append the rest of the string, but I'd really like to understand what (if anything) I'm doing wrong here.

Yevgeny Simkin
  • 27,946
  • 39
  • 137
  • 236
  • Can you give some example filenames, please? (Also, the manual way isn't so bad - you can assign characters in PHP, like `$fileName[0] = strtoupper($fileName[0]);`) – Ry- Jun 20 '12 at 01:55
  • Just in case this has been missed, ucfirst() doesn't lower case other letters, only capitalises the first. So if the second letter is already capitalised, then you need to srttolower() it first. – Robbie Jun 20 '12 at 02:01
  • @Robbie, I'm not actually concerned about the second letter, it can stay whatever it was. I just want to Cap the first one so it's easy to see the log file sitting right next to the script it's logging from (and I don't accidentally delete the script when I delete the log), but thanks for the clarification. – Yevgeny Simkin Jun 20 '12 at 02:10
  • @minitech, getUserInfo.php gets converted to gEtUserInfo.php, while bankCoin.php converts to BankCoin.php. I'm also noticing that this may have something to do with whether I call the script at the command line or via HTTP. Haven't had a chance to really test this out yet. – Yevgeny Simkin Jun 20 '12 at 02:16
  • Confirmed. this is only happening when I run it at the command line. When I call it through the browser it works as expected. – Yevgeny Simkin Jun 20 '12 at 02:24
  • For me `echo ucfirst('getUserInfo.php')` returns the expected result using `cli`; have you isolated the `ucfirst()` call enough? – Ja͢ck Jun 20 '12 at 02:39
  • yeah, I echo the $fileName string and it looks exactly right, and I trim() it just in case. Totally wacky, from the command line it alters the second char, via an HTTP request, it does everything as expected. – Yevgeny Simkin Jun 20 '12 at 05:42
  • Try `mb_convert_case()` instead. https://stackoverflow.com/a/68768405/2943403 – mickmackusa Aug 13 '21 at 20:26

3 Answers3

1

This is probably a bug further up the code, where you calculate the $dir and $filename. If the path has a slash or not... a probably solution is .

if (strpos('/', $filePath) === false) {
    $dir = '';    
    $fileName = $filePath;
} else {
    $dir = substr($filePath, 0, strrpos($filePath, "/") + 1);    
    $fileName = substr($filePath,strrpos($filePath, "/")+1);
}

But echo those values out and concetrate there

Robbie
  • 17,605
  • 4
  • 35
  • 72
  • as I note in my comment above, I have isolated this and it's happening exclusively when I call the php from the command line. Via an HTTP request it works as documented. And my values are all exactly what I expect them to be (at least inso far as I can inspect the characters). – Yevgeny Simkin Jun 20 '12 at 05:44
  • Yes, I read. $_SERVER["SCRIPT_FILENAME"] is relative (check the docs - relative if run explicity, absolute otherwise) and won't include a slash. So try the code in the answer and it should work for you for both "in the browser" (will include a slash) and "by command line" (won't include the slash). If not, then encho out $_SERVER['script_filename'] in both cases and add to your answer - then we can check that out. Cheers. – Robbie Jun 20 '12 at 05:49
0

You can forcefully downcase the file name before capitalizing the first letter. That is if all what you care about is capitalizing the first letter.

$fileName = ucfirst(strtolower($fileName));
Robert Wilson
  • 659
  • 1
  • 12
  • 28
  • as it happens, it does lowercase everything and then promptly upper cases the second character (just like it was doing before)! – Yevgeny Simkin Jun 20 '12 at 02:18
0

On the docs for ucfirst it says (with my emphasis):

Returns a string with the first character of str capitalized, if that character is alphabetic.

Depending on where you execute this script SCRIPT_FILENAME will return different results. Could it be possible that you execute the script from a different path, thus giving SCRIPT_FILENAME a relative path?

To test this theory, I ran the script below from some of your possible execution paths and saw possible examples include the prefix "./" and "/" which would likely not be considered as having alphabetic first characters.

<?php
error_reporting(E_ALL);
echo $_SERVER["SCRIPT_FILENAME"]; 
?>
buley
  • 28,032
  • 17
  • 85
  • 106