3

Okay - so I'm creating a dynamic CSS stylesheet, which I want to set up with an array.

First let me say that I'm not a PHP expert, but I somewhat know my way around it.

Here's my very basic array.

$visual_css = array (
    array(
        "selector"  => "body",
        "property"  => "background",
        "value"     => "#FFF",
        "property2" => "color",
        "value2"    => "#000",
        "type"      => "css"
    )
);

So we have a selector, and two properties with values.

I now want to create the stylesheet, but I'm running into problems due to my lack of PHP knowledge.

foreach ($visual_css as $value) {
    switch ($value['type']) {
        case "css":

            // Open selector
            echo ( !empty($value['selector']) ? $value['selector'] . '{' : null );

            foreach ($value as $key => $item) {
                foreach ($value as $key2 => $item2) {
                    //Match only the id's against the key
                    if (preg_match('/^property/i', $key) && preg_match('/^value/i', $key2)) {
                        // First property
                        echo ( !empty($item) ? $item . ':' : null );
                            echo ( !empty($item2) ? $item2 . ';' : null );
                    }
                }

            }

            // Close selector
            echo ( !empty($value['selector']) ? '}' : null );

        break;
    }
}

Now I know this code isn't correct, as it's outputting the following in the stylesheet:

body{background:#FFF;background:#000;color:#FFF;color:#000;}

This is the desired result:

body{background:#FFF;color:#000;}

So basically, I want to be able to create an unlimited number of properties and values with an incrementing number after them, and have the code write it out.

Can anyone help me?

Thanks!

2 Answers 2

8

So my approach uses a multidimensional array instead of a flat array to nest properties of selectors in sub-arrays. This way your approach is much more concise by first looping through the first layer, and then going through the children of each parent and composing the CSS for each property / value pair. It also makes iteration a cinch as opposed to having to inspect the values of keys to locate which pair you're at. If you need a different output format, your iteration code can decide that, and it should be left out of the structure

$visual_css = array (
    'body'  => array(
        'background'    => '#FFF',
        'color'         => '#000'
    )
);

$output = '';
foreach($visual_css as $k => $properties) {
    if(!count($properties))
        continue;

    $temporary_output = $k . ' {';

    $elements_added = 0;

    foreach($properties as $p => $v) {
        if(empty($v))
            continue;

        $elements_added++;

        $temporary_output .= $p . ': ' . $v . '; ';
    }

    $temporary_output .= "}\n";

    if($elements_added > 0)
        $output .= $temporary_output;
}

echo $output;
// body {background: #FFF; color: #000; }
Sign up to request clarification or add additional context in comments.

6 Comments

+1 for the answer, but you should explain what you've done here.
Just added some comments :) Honestly I thought I had, but I suppose I was just thinking in my head haha
Wow that was fast. Thanks a lot for simplifying it as well! Is it also possible to only write out the css if at least one of the values in the array is set? So if neither background or color have a value, the css for that element isn't created, but if background has a value and color doesn't the css is created but only with that one property and value? Thanks!!
Absolutely, I just added the additional checks to make sure the nested values + the actual css property values have values. You can see them in my if(!count and if(empty additions to the code
Amazing, almost perfect. However, if background and color are empty, the stylesheet outputs an empty body{} tag. Is it possible to check if all of the values are empty, and if so, don't output anything? If not, this code will do just fine. I really, really appreciate your time!
|
1

In your example you are looping over the same array twice, in this piece of code:

foreach ($value as $key => $item) {
    foreach ($value as $key2 => $item2) {

If you structured your data in a more logical way, you could make a cleaner loop code, too. I'd suggest you to structure the array with each property&value as a separate sub-array, for example:

$visual_css = array(
    array(
        'selector' => 'body',
        'properties' => array(
            'background' => '#fff',
            'color' => '#000'
        )
    )
    // ... etc ...
);

And then you can easily loop through it like this:

foreach ($visual_css as $selector)
{
    echo $selector['selector'].' { ';
    foreach ($selector['properties'] as $name => $value)
    {
        echo $name.': '.$value.'; ';
    }
    echo ' } ';
}

1 Comment

Thanks a lot for explaining what I did wrong and showing a better way to do it. I really appreciate the time and effort! Thanks! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.