如何使用数组编程PHP循环?

In a wordpress site for a dental clinic, there are several services (e.g. Orthodontics). These services are like "categories", using both names and slug-names. (e.g. Orthodontics / cat_orthodontics).

In the frontend, the services page shows every category, the name of the category and a description. I just need to put images related to every category.

I noticed that in the category file (category.php) that creates the area to show every one of these images, there are several lines that control the frontend:

<?php   
                    $args = array( 'taxonomy' => 'services_category', 'hide_empty' => '0', 'exclude' => $pixhealth_deps);                           
                    $pixhealth_categories = get_categories ($args);                             
                    if( $pixhealth_categories ):
                        foreach($pixhealth_categories as $pixhealth_cat) :
                            $pixhealth_t_id = $pixhealth_cat->term_id;
                            $pixhealth_cat_meta = get_option("services_category_$pixhealth_t_id");
                            $pixhealth_link = !isset($pixhealth_cat_meta['pix_serv_url']) || $pixhealth_cat_meta['pix_serv_url'] == '' ? get_term_link( $pixhealth_cat ) : $pixhealth_cat_meta['pix_serv_url'];
                ?>                                      
                            <div class="departments-item ">
                                <span class="icon-round bg-color_second helper">
                                    <i class="icon <?php echo esc_attr($pixhealth_cat_meta['pix_icon']) ?>"></i>
                                </span>
                                </div>
                                <h3 class="ui-title-inner"><?php echo wp_kses_post($pixhealth_cat->name) ?></h3>
                                <p class="ui-text"><?php echo pixhealth_limit_words($pixhealth_cat->description, 20) ?></p>
                                <a class="btn btn_small" href="<?php echo esc_url($pixhealth_link) ?>"><?php _e("READ MORE", "PixHealth") ?></a>
                            </div>
                <?php                           
                         endforeach;
                    endif; ?>

The "departments-item" creates every displayed service in the frontend:

<div class="departments-item ">

To put images I need to create a new div for every service and delete the <i class="icon"> because I don't want to show icons for every service. I need images.

So I tried this:

<?php   
                    $args = array( 'taxonomy' => 'services_category', 'hide_empty' => '0', 'exclude' => $pixhealth_deps);                           
                    $pixhealth_categories = get_categories ($args);                             
                    if( $pixhealth_categories ):
                        foreach($pixhealth_categories as $pixhealth_cat) :
                            $pixhealth_t_id = $pixhealth_cat->term_id;
                            $pixhealth_cat_meta = get_option("services_category_$pixhealth_t_id");
                            $pixhealth_link = !isset($pixhealth_cat_meta['pix_serv_url']) || $pixhealth_cat_meta['pix_serv_url'] == '' ? get_term_link( $pixhealth_cat ) : $pixhealth_cat_meta['pix_serv_url'];
                ?>                                      
                            <div class="departments-item ">
                                <!--<span class="icon-round bg-color_second helper">
                                    <i class="icon <?php /*?><?php echo esc_attr($pixhealth_cat_meta['pix_icon']) ?><?php */?>"></i>
                                </span>-->
                                <?php servicios=array('cirugia_oral','endodoncia','estetica_dental','implantes_dentales','odontopediatria','ortodoncia','periodoncia','rehabilitacion_oral');   ?>
                                <div class="inner-departments <?php echo wp_kses_post($pixhealth_cat->name) ?>">

                                </div>
                                <h3 class="ui-title-inner"><?php echo wp_kses_post($pixhealth_cat->name) ?></h3>
                                <p class="ui-text"><?php echo pixhealth_limit_words($pixhealth_cat->description, 20) ?></p>
                                <a class="btn btn_small" href="<?php echo esc_url($pixhealth_link) ?>"><?php _e("READ MORE", "PixHealth") ?></a>
                            </div>
                <?php                           
                         endforeach;
                    endif; ?>

I added an array:

<?php servicios=array('cirugia_oral','endodoncia','estetica_dental','implantes_dentales','odontopediatria','ortodoncia','periodoncia','rehabilitacion_oral'); ?>

and added a line to create every div:

<div class="inner-departments <?php echo wp_kses_post($pixhealth_cat->name) ?>">

I noticed on another line that: <?php echo wp_kses_post($pixhealth_cat->name) ?> echoes the name of every category, so I decided to use this inside my new div to create every category class.

However, I would like to use the names from the array and not the names from every category because some names have special characters like "ñ" and this cannot be used as a class.

I don't know how to relate the names of the categories to every item in the array, using perhaps a foreach for every item in the array with every name in the categories? The idea is to create a unique class for every category so I can then add images using CSS for every class.

If you have a better idea how I can add unique images to every class let me know.

Thank you for any help.

Okay I think I understand what you're trying to do.

You'll need to add the category names to your array. Code is untested, so you may need to debug, but the idea is there.

<?php   
    $args = array( 'taxonomy' => 'services_category', 'hide_empty' => '0', 'exclude' => $pixhealth_deps);                           
    $pixhealth_categories = get_categories ($args);    

    if( $pixhealth_categories ):
        $servicios=array(
            'category_name1'=>'cirugia_oral',
            'category_name2'=>'endodoncia',
            'category_name3'=>'estetica_dental',
            'category_name4'=>'implantes_dentales',
            'category_name5'=>'odontopediatria',
            'category_name6'=>'ortodoncia',
            'category_name7'=>'periodoncia',
            'category_name8'=>'rehabilitacion_oral');   

        foreach($pixhealth_categories as $pixhealth_cat) :
            $pixhealth_t_id = $pixhealth_cat->term_id;
            $pixhealth_cat_meta = get_option("services_category_$pixhealth_t_id");
            $pixhealth_link = !isset($pixhealth_cat_meta['pix_serv_url']) || $pixhealth_cat_meta['pix_serv_url'] == '' ? get_term_link( $pixhealth_cat ) : $pixhealth_cat_meta['pix_serv_url'];
?>                                      
            <div class="departments-item ">
                <!--<span class="icon-round bg-color_second helper">
                    <i class="icon <?php /*?><?php echo esc_attr($pixhealth_cat_meta['pix_icon']) ?><?php */?>"></i>
                </span>-->

                <div class="inner-departments <?php echo $servicios[$pixhealth_cat->name]; ?>">
                 <!-- div content -->
                </div>

                <h3 class="ui-title-inner"><?php echo wp_kses_post($pixhealth_cat->name) ?></h3>
                <p class="ui-text"><?php echo pixhealth_limit_words($pixhealth_cat->description, 20) ?></p>
                <a class="btn btn_small" href="<?php echo esc_url($pixhealth_link) ?>"><?php _e("READ MORE", "PixHealth") ?></a>
            </div>
<?php                           
        endforeach;
    endif; ?>

As I see your problem is coming from special characters.

I would not add any extra arrays to the code (maintenance becomes much harder).

  1. What does the $pixhealth_categories variable hold? You should print it out to the screen (e.g. print_r( $pixhealth_categories ); ). You can look up what should be in the array: https://developer.wordpress.org/reference/functions/get_categories/.
  2. I would change the get_categories() to get_terms() (much more versatile return value - I suggest printing it out too, link: https://developer.wordpress.org/reference/functions/get_terms/). So, the new $pixhealth_categories array holds much more information - even the slug value of the category. The slug does not use special characters, so it can be used as CSS classnames.
  3. And there's a little mistake in your original code: servicios=array('cirugia_oral','endodoncia','estetica_dental','implantes_dentales','odontopediatria','ortodoncia','periodoncia','rehabilitacion_oral'); should begin with a $ sign.

So, I think I would try this, and then debug, if it fails:

<?php   
$args = array( 'taxonomy' => 'services_category', 'hide_empty' => '0', 'exclude' => $pixhealth_deps);                           
$pixhealth_categories = get_terms($args);                             
if( $pixhealth_categories ):
    foreach($pixhealth_categories as $pixhealth_cat) :
        $pixhealth_t_id = $pixhealth_cat->term_id;
        $pixhealth_cat_meta = get_option("services_category_$pixhealth_t_id");
        $pixhealth_link = !isset($pixhealth_cat_meta['pix_serv_url']) || $pixhealth_cat_meta['pix_serv_url'] == '' ? get_term_link( $pixhealth_cat ) : $pixhealth_cat_meta['pix_serv_url'];
?>                                      
        <div class="departments-item ">
            <!--<span class="icon-round bg-color_second helper">
                <i class="icon <?php /*?><?php echo esc_attr($pixhealth_cat_meta['pix_icon']) ?><?php */?>"></i>
            </span>-->
            <?php $servicios=array('cirugia_oral','endodoncia','estetica_dental','implantes_dentales','odontopediatria','ortodoncia','periodoncia','rehabilitacion_oral');   ?>
            <div class="inner-departments <?php echo wp_kses_post($pixhealth_cat->slug) ?>">

            </div>
            <h3 class="ui-title-inner"><?php echo wp_kses_post($pixhealth_cat->name) ?></h3>
            <p class="ui-text"><?php echo pixhealth_limit_words($pixhealth_cat->description, 20) ?></p>
            <a class="btn btn_small" href="<?php echo esc_url($pixhealth_link) ?>"><?php _e("READ MORE", "PixHealth") ?></a>
        </div>
<?php                           
     endforeach;
endif; ?>

The basic thought in my suggestion is to change the get_categories() to get_terms() - and then everything can be put in place as needed. :)

Then there's a "B" solution: just print out the names into data-* HTML5 attributes (e.g. data-catname), and use the [data-*="XYZ"] selector in the CSS, instead of normal classes. (This seems to me as a hack, but the special characters become irrelevant as strings.)