Category Archives: PHP

Everything that is related to PHP

CSS3 easier properties writing

CSS3 easier properties writing

CSS3’s new features are really nice. But unfortunately, all the browsers don’t support everything (in fact, no browser support it entirely), but they provide vendor-dependent properties that allow to use it. So to use them, you need to duplicate your code, with all the problems that it can bring. I present you here a solution to write less CSS for the same result, without having to take care of vendor-specific options.

Vendor-specific properties are a pain in the ass !

Let’s say that you want to use a new property in CSS3. For this example, we will use border-image. According to W3Schools, you simply cannot use it in IE (duh !). In Firefox, Chrome and Opera, you have to use vendor specific rules to make this property work. So you need to write :

div
{
border-image:url(border.png) 30 30 round;
-moz-border-image:url(border.png) 30 30 round; /* Firefox */
-webkit-border-image:url(border.png) 30 30 round; /* Safari and Chrome */
-o-border-image:url(border.png) 30 30 round; /* Opera */
}

(example taken from http://www.w3schools.com/css3/css3_borders.asp)

Okay, this works. But you wrote four lines to get only one effect. And if you want to change this property, you will have change it four times instead of only once. Your code become harder to read and longer, for so few. And I don’t even talk about misspelling or different behavior because the -webkit property is different from the -moz property, but you didn’t notice it !

Well, you got my point, this is pain in the ass.

Couldn’t we get rid of it ?

In fact, yes, you can. The good news about those vendor-specific properties is that they have the same syntax as CSS3, with just a prefix that is different for each browser (-moz-, -o-, -webkit-, -ms-…). All you need to do is to duplicate the rule for each vendor-specific prefix, just like in the code above. And a simple parser should be able to do that for you.

I already wrote it, so you don’t even have to create your own (aren’t I kind ? :-)). It is working nicely (in fact, this blog uses it right now), so you shouldn’t have problem with it. That said, if  you find an error, some properties that are missing or shouldn’t be converted, let me know !

Also, I’m working on a system that takes a CSS file, convert it and saves it in a cache, so that you can use it directly in your website without going through this page. If you change your CSS, the system detects it and recompile the converted version for you. I will probably publish the system before Christmas, so stay tuned !

A PHP Command-line interface parser

A PHP Command-line interface parser

Today, I decided to build a simple, but highly parametrable script that takes a bunch of images and resizes them with a given method. My first problem was : how to make a good command line arguments parser, so that I don’t have to write each argument in a specific order, or not putting some arguments at all, using a default value…
In bash, this is quite simple, but I wanted to use PHP for the script, so that I could use the GD library that I know well.

Then I found this class, made by Diego Feitosa, that looked nice, but wasn’t exactly what I wanted : I was forced to use an option (i.e. “-something <param>”) for each argument in the command line. It is nice for defining the behaviour of the script, but if you want to script something that process files, you just can’t – or only one file at a time.

In fact, this is exactly what I was doing : processing a lot of files. But with this parser, I couldn’t. So I decided to hack it a bit…

This code is an extended version of the CLI Parser of Diego Feitosa, which allows the user to pass arguments that are not options. I also made other modifications to the script :

  • added a method to check if an argument is valid as a non option (by default, everything that doesn’t start with ‘-‘ can be a non-option)
  • improved usage description : the type awaited by an option is shown, better indentation
  • improved error messages : if the type in the command line doesn’t match with an option, the error is shown. In the version of Diego, only the usage message was shown.
  • auto-inclusion of the option types
  • new option types : Positive Numeric, Negative Numeric, Integers, Enum

You can find the code here.

Here is an example of the usage of this parser. This example is also located in the source code provided above :

require_once('CliParser.inc');
$clistring = new CliTokenString("-c");
$clistring->setDescription("It requires a string");

$clihelp = new CliTokenBoolean("--help");
$clihelp->setDescription("Token that shows a help message");

$clisingleton = new CliTokenBoolean("-e");
$clisingleton->setDescription("It don't require any value. The existence of this argument is enough");

$clibool = new CliTokenBoolean("-b");
$clibool->setDescription("Boolean token");

$clidir = new CliTokenDirectory("-d");
$clidir->setDescription("This token require a directory path as argument. If the argument isn't a directory path, an error message will appear.");

$clifile = new CliTokenDirectory("-f");
$clifile->setDescription("This token require a file path as argument. If the argument isn't a file path, an error message will appear.");

$cliint = new CliTokenInteger("-i");
$cliint->setDescription("This token require an integer path as argument. If the argument isn't an integer, an error message will appear.");

$clienum = new CliTokenEnum("-enum", array('the', 'different', 'values', 'accepted'));
$clienum->setDescription("This token requires its argument to be one of the values specified");

class MyCliParser extends CliParser
{
  public function getHelpMessage()
  {
    global $argv;
    echo sprintf("Usage: %s [options] <file(s)>\nOptions :\n", $argv[0]);
    $this->getDescriptions();
    echo "\n";
    exit;
  }
}

//Building the parser and parsing the arguments
$cli = new MyCliParser($_SERVER["argv"]);
$cli->register($clihelp, false); // false because it not require an argument
$cli->register($clistring);
$cli->register($clisingleton, false); // false because it not require an argument
$cli->register($clibool);
$cli->register($clidir);
$cli->register($clifile);
$cli->register($cliint);
$cli->register($clienum);
$cli->parse();

//Showing the help message if asked
if ($clihelp->getValue())
{
  $cli->getHelpMessage();
  exit;
}

//Showing the options
var_dump($clistring->getValue());
var_dump($clisingleton->getValue());
var_dump($clibool->getValue());
var_dump($clidir->getValue());
var_dump($clifile->getValue());
var_dump($cliint->getValue());

//Showing the non options
var_dump($cli->getNonOptions());

/* Some commands :
php example.php --help
=> will show the help message

php example.php -c foo
=> the $clistring token will be set

php example.php -e -c foo
=> the $clisingleton token will be set

php example.php nonoption1 -i 42
=> one non-option argument : nonoption1

php example.php -i 42 nonoption1
=> same thing, different order

php example.php -i 42.5
=> shows an error : 42.5 is not an integer
*/