I'm getting used to printf, would this be an acceptable use of it?

try{
    	   $db = new PDO("mysql:host=localhost;dbname=database", 'root', '');
    	   $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    	}  catch(PDOException $e){
    		echo $e->getMessage();
    		die();
    	}


    function test(PDO $db)
    {
        try
        {
            $query = $db->prepare("SELECT * FROM music");
            $query->execute();
            $text = "";
            foreach($query as $music) 
            { 
                printf('<div class="music">%s</div>', htmlspecialchars($music["artist"])); 
            } 

        }catch(PDOEXception $e)
        {
            return $text .="Try again later";
        }
    }

echo test($db);

    If you're going to directly output the <div> (using printf or whatever) then you ought to do the same with the "Try again" message, so that the behaviour is consistent. Contrariwise, if you want to return the string in both cases instead you'd use [man]sprintf[/man] instead, concatenating its return values onto [font=monospace]$text[/font] to return at the end ofthe loop.

    In short, either

     echo "Try again later";

    or

    $text .= sprintf('<div class="music">%s</div>', htmlspecialchars($music['artist']));

    Which one you use (output or return) depends on how "low-level" you reckon the function is - some function is going to have to produce output some time and maybe the time is now.

      Yeah, since your test code appears to expect the function to return something...

      echo test($db);
      

      ...I would use sprintf() to append to $text, then return it after the loop.

      It's sort of a bit "messy" to combine HTML output with database access stuff, so in a "real" use case I'd probably grab the data from the DB in one function, and have it return something iterable (maybe an array, possibly a PDOStatement object, or a user-defined object that implements Iterator or such). Then you could send that iterable "thing" to an output function that would generate the actual HTML (or another for JSON, or XML, or whatever else you might need 🙂 ).

        Well I was trying things like this to start off with and build from there but I'm sure I'm barking up the wrong tree

        try{
            	   $db = new PDO("mysql:host=localhost;dbname=database", 'root', '');
            	   $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            	}  catch(PDOException $e){
            		echo $e->getMessage();
            		die();
            	}
        
        
            function test(PDO $db, $result)
            {
                try
                {
                    $query = $db->prepare("SELECT * FROM music");
                    $query->execute();
                    $result = $query->fetchAll();
                    $text = "";
        
                }catch(PDOEXception $e)
                {
                    return $text .="Try again later";
                }
            }
        
        $results = array("result" => "artist");
        
        foreach($results as $key => $value)
        {
            echo $value;
        } 
        
        

        I'm not really great with final output's er...what should I search for?

          Totally untested, but this shows how you can functionalize each piece of the puzzle -- perhaps overkill for this small case, but still useful for showing how I might try to compartmentalize things (and try to use meaningful yet terse names for things).

          <?php
          
          try{
              $db = db();
              ULOut(allArtists($db));
          } catch(PDOException $e){
              die('PDO error:'.PHP_EOL.$e->getMessage());
          } catch(Exception $e) {
              die('Other error:'.PHP_EOL.$e->getMessage());
          }
          
          function db()
          {
              $db = new PDO("mysql:host=localhost;dbname=database", 'root', '');
              $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
              return $db;
          }
          
          function allArtists(PDO $db)
          {
              $query = $db->prepare("SELECT artist FROM music");
              $query->execute();
              $result = array();
              while($artist = $query->fetchColumn()) {
                  $result[] = $artist;
              }
              return $result;
          }
          
          function ULOut(array $data)
          {
              echo "<ul>\n";
              foreach($data as $item) {
                  printf("<li>%s</li>\n", htmlspecialchars($item));
              }
              echo "</ul>\n";
          }
          

            PS: An enhancement if you want to be able to set specified class values in your HTML output. 🙂

            <?php
            
            try{
                $db = db();
                ULOut(allArtists($db), 'music', 'artist');
            } catch(PDOException $e){
                die('PDO error:'.PHP_EOL.$e->getMessage());
            } catch(Exception $e) {
                die('Other error:'.PHP_EOL.$e->getMessage());
            }
            
            function db()
            {
                $db = new PDO("mysql:host=localhost;dbname=database", 'root', '');
                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                return $db;
            }
            
            function allArtists(PDO $db)
            {
                $query = $db->prepare("SELECT artist FROM music");
                $query->execute();
                $result = array();
                while($artist = $query->fetchColumn()) {
                    $result[] = $artist;
                }
                return $result;
            }
            
            function ULOut(array $data, $listClass=null, $itemClass=null)
            {
                printf(
                    "<ul%s>\n",
                    !empty($listClass) ? ' class="'.htmlspecialchars($listClass).'"' : ''
                );
                foreach($data as $item) {
                    printf(
                        "<li%s>%s</li>\n",
                        !empty($itemClass) ? ' class="'.htmlspecialchars($itemClass).'"' : '',
                        htmlspecialchars($item)
                    );
                }
                echo "</ul>\n";
            }
            

              It's a ternary operator? I didn't know they could be like that

               !empty($listClass) ? ' class="'.htmlspecialchars($listClass).'"' : '' 
              

                Yep. I don't often use ternary operators, but when I do, they're often in (s)printf() statements. 🙂

                You could be even more functional and move those operations into a function, and then just call it, for even DRYer code.

                function classIfSet($class)
                {
                    $result = '';
                    if(!empty($class)) {
                        $result = ' class="'.htmlspecialchars(trim($class)).'"';
                    }
                    return $result;
                }
                
                function ULOut(array $data, $listClass=null, $itemClass=null)
                {
                    printf(
                        "<ul%s>\n",
                        classIfSet($listClass)
                    );
                    foreach($data as $item) {
                        printf(
                            "<li%s>%s</li>\n",
                            classIfSet($itemClass),
                            htmlspecialchars($item)
                        );
                    }
                    echo "</ul>\n";
                }
                

                Code...refactor...repeat. 🙂

                  Ahh I thought ternary operators might have been used more often

                    cluelessPHP;11063709 wrote:

                    Ahh I thought ternary operators might have been used more often

                    It depends on the coder, I suppose. I suspect the PHP compiler ends up doing the same thing whether you use the ternary operator or an if/else block. In situations where it's a straight-forward operation, it can clean up the code a bit sometimes, but the moment you find yourself nesting a ternary expression within a ternary expression, you're probably writing code I don't ever want to have to debug. 😉 And as in the case above where I was doing almost the same exact thing in two different ternary expressions, it seemed a good case for DRYing things up and putting it into its own function. Within that function definition I didn't see anything gained by using the ternary operator, so went to a more "normal(?)" format.

                      Ahh, I was following some tutorial not long ago that used them for input so I'd thought like I said it was just a "normal" thing to do, although the example given was part of the Singleton pattern

                      <?php
                      class Input{
                      	public static function exists($type = 'post'){
                      		switch($type){
                      		case 'post':
                      			return(!empty($_POST)) ? true : false;
                      		break;
                      
                      	case 'get';
                      		return(!empty($_GET)) ? true : false;
                      	break;
                      
                      	default;
                      		return false;
                      	break;	
                      	}
                      }
                      
                      	public static function get($item){
                      	if(isset($_POST[$item])){
                      		return $_POST[$item];
                      		}else if(isset($_GET[$item])){
                      			return $_GET[$item];
                      		}
                      		return '';
                      	}	
                      
                      }
                      
                      
                      
                        cluelessPHP wrote:
                        return(!empty($_GET)) ? true : false;

                        This particular instance being one which rubs me up the wrong way.

                        The negation already evaluates to either [font=monospace]true[/font] or [font=monospace]false[/font] even if [man]empty[/man] didn't already do so.

                        This statement says "If the negation of empty($GET) is true, then return true, otherwise return false". It's exactly equivalent to

                        return !empty($_GET);

                        I think it's a leftover from old C code, which didn't have booleans, and [font=monospace]TRUE[/font] and [font=monospace]FALSE[/font] had to be integers defined by the programmer, and you couldn't necessarily assume that [font=monospace]TRUE[/font] would be equal to the result of casting font=monospace[/font] to an integer, or that such an integer would be evaluated as "true" in a boolean expression, or that [font=monospace]FALSE[/font] would be the negation of [font=monospace]TRUE[/font], and if all those things did hold the conditional would get optimised out by the compiler anyway (rewriting [font=monospace]f(x) ? a : b[/font] as font=monospace * (a - b) + b[/font], and if [font=monospace]a==1[/font] and [font=monospace]b==0[/font] then obvious simplifications follow). None of which applies to PHP.

                          Oh, I C

                          There was more to the tutorial than that, hmm maybe picked up some bad habits without knowing it (and I already had too many)

                            cluelessPHP;11063737 wrote:

                            Oh, I C

                            There was more to the tutorial than that, hmm maybe picked up some bad habits without knowing it (and I already had too many)

                            The danger of web tutorials: not all are created equal. 🙂

                              NogDog;11063783 wrote:

                              The danger of web tutorials: not all are created equal. 🙂

                              True I guess, but he "seemed" to know what he was talking about. I put the full code in echo lounge, he has a small YouTube channel so that's the results of me sitting listening and typing what he was doing

                                Write a Reply...