Tips on formatting PHP output?

GJSNeptune

[H]F Junkie
Joined
Mar 31, 2004
Messages
12,372
Old thread was deleted, but this time I get to be more specific and create it from home with my files. I only remember maw's suggestion of using the substr() command, which seems like a pretty good way to do this.

In addition, I wanted someone's help regarding passing variables through the URL and webcrawlers not going past the question marks. Someone posted a link about working around that or changing them in the code but still rendering a URL-variable. Please post that again if you come across this.

Since the PHP tag displays variables in an eye-straining blue, I'll just use the CODE tag.

Code:
$query  = "SELECT title FROM pieces";
$result = mysql_query($query);

while($row = mysql_fetch_assoc($result))
    {
    echo "<a href=\"poetry.php?piece={$row['title']}\">{$row['title']}</a> | ";
    }

The above pulls the titles from the database table of writing pieces and displays them as links like this: Title | Title | Title | Title |, only I don't want the last link to have the "|" after it.

Also, would it be better to "title" each piece by an ID number? I'm a little uneasy about having %20 filler in URLs.

The titles will be displayed in a separate div from the content. The content div should be empty until a title is clicked, but I want the content div to display the title with an underline. I can pass the variable through and display the title in the content div when clicked, but the underline is always in there. How can I keep that div empty until a title is clicked, or maybe have "Please choose a piece" displayed.
 
here is how you solve your title | title | issue: assuming what you originally posted works, that is.
$query = "SELECT title FROM pieces";
$result = mysql_query($query);

while($row = mysql_fetch_assoc($result))
{
$titles[] = "<a href=\"poetry.php?piece={$row['title']}\">{$row['title']}</a>";
}

echo implode(' | ', $titles);
 
to handle the extra | on the right, there are basically 2 options

put the data in an array first then use implode
Code:
$arr = array();
while ($row = mysql_fetch_assoc($result)) {
    $arr[] = sprintf('<a href="%1$s">%1$s</a>', $row['title']);
}

echo implode(' | ', $arr);
sprintf in case you're not familiar with it

alternatively use output buffering and trim the final |
Code:
ob_start();
while ($row = mysql_fetch_assoc($result)) {
    echo "<a href=\"poetry.php?piece={$row['title']}\">{$row['title']}</a> | ";
}

$content = ob_get_contents();
ob_end_clean();

echo rtrim($content, '| ');

i'd probably go with the first way personally

as far as the querystring (stuff after the ?) and search engines, you could look into using mod_rewrite, which you can use to make apache map a url like /poetry/mytitle to /poetry.php?piece=mytitle, but that's a whole topic itself
 
In addition, I wanted someone's help regarding passing variables through the URL and webcrawlers not going past the question marks. Someone posted a link about working around that or changing them in the code but still rendering a URL-variable. Please post that again if you come across this.
look up mod-rewrite. search for tutorials or whatnot.

Also, would it be better to "title" each piece by an ID number? I'm a little uneasy about having %20 filler in URLs.
yeah, that is a good idea to keep things simpler.
 
Ah, mod-rewrite. That's it. Thanks. Maybe that site is still in my history. Thanks for the quick replies. The implode method worked very well without changing my code much. Thanks everyone.

Anyone know how I can keep the content div empty or generic until a title is clicked?


Also, I want to make sure my table is most efficient. It's just to store writing pieces, so it only needs to be simple. I was thinking just four fields. id (INT), title (TEXT), text (LONGTEXT), and maybe date (TIMESTAMP) because later I want to implement a News section to display the newest pieces I've added. Is that all I need? Is the TEXT type okay for numbers?
 
Yeah Mod_Rewrite for Apache, and ISAPI_Rewrite for Windows/IIS. There is basic (lite) version of it that is free for windows.
 
Need some help on some things that are probably very simple.

1) My titles are displaying perfectly, although eventually I'll have to start putting titles on a second line, and I don't yet know how to parse output text. I'll need to break after a whole title and make sure the next title (assuming it's more than one word) doesn't get split up between lines.

My title code so far:
Code:
<?php
require("config.php");
require("opendb.php");

$query = "SELECT id, title FROM pieces";
$result = mysql_query($query);

while($row = mysql_fetch_assoc($result))
{
$titles[] = "<a href=\"poetry.php?piece={$row['id']}\">{$row['title']}</a>";
}

echo implode(' | ', $titles);
require("closedb.php");
?>

2) I haven't dived into mod-rewrite (it's a little too much right now), but I changed my URLs over to id numbers instead of the titles of the pieces. Poetry pieces are 100s, Fiction 200s, Nonfiction 300s, etc. I have the URL passing successfully, and when I click a title the id displays above the underline, but I don't know exactly how to have PHP match the id number with its corresponding title. I'm guessing I need another function after the $piece is passed.

I want the underline not to appear until a title is clicked, and eventually I'll need to know how to paginate longer pieces. Right now I'm just using poetry for the development.

twodivs.png


Clicking on Mayflies (which is ?piece=101):
twodivs2.png


The code so far:
Code:
<?php
require("config.php");
require("opendb.php");

    $piece = $_GET['piece'];
    echo "<h3>$piece</h3>";

require("closedb.php");
?>

I know you're thinking that I just haven't read enough and/or I don't have the head for it. I've read a lot, but I need hands-on experience to learn, and I learn best seeing it and replicating it.
 
2) I haven't dived into mod-rewrite (it's a little too much right now), but I changed my URLs over to id numbers instead of the titles of the pieces. Poetry pieces are 100s, Fiction 200s, Nonfiction 300s, etc. I have the URL passing successfully, and when I click a title the id displays above the underline, but I don't know exactly how to have PHP match the id number with its corresponding title. I'm guessing I need another function after the $piece is passed.

you'll need to query your database to figure it out. new code in bold, assuming your content in the database is stored in a field named "text".

Code:
<?php
require("config.php");
require("opendb.php");

[b]$query = "SELECT text FROM pieces WHERE id=". mysql_escape_string($_GET['piece']);

$result = mysql_query($query);

$content = mysql_fetch_assoc($result);
[/b]
$query = "SELECT id, title FROM pieces";
$result = mysql_query($query);

while($row = mysql_fetch_assoc($result))
{
$titles[] = "<a href=\"poetry.php?piece={$row['id']}\">{$row['title']}</a>";
}

echo implode(' | ', $titles);
require("closedb.php");
[b]echo $content['text'];[/b]
?>
 
Thanks, hofan! I'll be trying this when I get home from work.

Anyone else have input?
 
I'm having some trouble echoing a variable with non-PHP code around it.

Code:
<?php
require("config.php");
require("opendb.php");

    $query = "SELECT text, title FROM pieces WHERE id=". mysql_escape_string($_GET['piece']);
    $result = @mysql_query($query);
    $content = @mysql_fetch_assoc($result);

require("closedb.php");
    echo $content['title'];
    echo $content['text'];
?>

hofan41, I took your code and applied it to my two divs. I had to add some @ symbols to get rid of the error that displayed until a title was clicked:

Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource

Right now I can display the content of each poem as well as the title, but there's no CSS applied so all the text runs together, and for some reason HTML and CSS tags give me errors.

What I've tried:
Code:
echo "<h3>$content['title']</h3>";
echo "<p>$content['text']</p>";
Code:
echo $content"<h3>['title']</h3>";
echo "<p>$content"<h3>['text']</p>";

Usually results in the Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING error.
 
First, add some code to check to see if you have a variable to send to the db, or else don't connect to it. Hiding the error codes is a bad idea :p

Second, its:

Code:
echo "<h3>$content[title]</h3>";
echo "<p>$content[text]</p>";

Remove the 's from your db result variable.

The other attempt has very broken html and php usage.
 
First, add some code to check to see if you have a variable to send to the db, or else don't connect to it. Hiding the error codes is a bad idea :p

I know! I knew what lines were doing it, but it was beyond me what was causing it. What I really want to do is to display something like, "Please choose a title" when no title has been selected. How do I keep the database from being queried until a title is chosen?

Second, its:

Code:
echo "<h3>$content[title]</h3>";
echo "<p>$content[text]</p>";

Remove the 's from your db result variable.

The other attempt has very broken html and php usage.

Thanks. Worked well. When are the apostropohes needed and not needed? Or are they not needed in the first section of code either?
 
Probably not needed in earlier parts either... though I think it depends on if you use the "s for echo, I always " my echo's so maybe thats whats different.

Re: how to do it.. something like:

Code:
If ($yourtitlevar != "") { // Does not equal blank, thus has a value.. can also use isset($var) as well 
// Do database stuff
} else {
echo "<h3>Choose a title</h3>";
}

I haven't looked much at your actual code, just a few things I noticed in that last post as I skimed it, so if you need more detailed info than this please let me know :)
 
$query = "SELECT title FROM pieces";
$result = mysql_query($query);

if($row = mysql_fetch_assoc($result))
echo "<a href=\"poetry.php?piece={$row['title']}\">{$row['title']}</a>";

while($row = mysql_fetch_assoc($result))
{
echo " | <a href=\"poetry.php?piece={$row['title']}\">{$row['title']}</a>";
}
 
$query = "SELECT title FROM pieces";
$result = mysql_query($query);

if($row = mysql_fetch_assoc($result))
echo "<a href=\"poetry.php?piece={$row['title']}\">{$row['title']}</a>";

while($row = mysql_fetch_assoc($result))
{
echo " | <a href=\"poetry.php?piece={$row['title']}\">{$row['title']}</a>";
}

We're past the title stuff, but thank you.
 
I'm making a lot of progress. Many thanks to jmackay.

One question to which I can't find an answer revolves around variables and the INSERT function. My goal is for id to auto-increment and date to timestamp, but leaving them "blank" isn't working, and jmackay mentioned newer versions of MySQL don't allow for that anyway. I tried having both variables set to Null and Not Null, but nothing worked. Do I even need to mention them in the code, or what value do they need?

Is my table set up correctly?

writingstructure.png


Code:
<?php
require("db/config.php");
require("db/opendb.php");

$id = "";
$title = $_POST[title];
$text = $_POST[text];
$type = $_POST[type];
$date = "";
$year = $_POST[year];

$query = mysql_query("INSERT INTO pieces(id, title, text, type, date, year) VALUES ('$id', '$title', '$text', '$type', '$date', '$year')") or die (mysql_error());

    require("db/closedb.php");
    require("success.php");
?>

Also, eventually I'll have the year attribute be automatically processed, but right now I'll be entering it manually because I'll be uploading work from previous years. Will the same value or protocol for id and date apply to year?
 
Oh not sure if my last PM didn't work, but try sending ID a value of 1 (Also make sure its set to "auto_increment", for some reason its not showing up in your extra column).

You could also try just taking it out of your insert query all together.

Code:
$query = mysql_query("INSERT INTO pieces(title, text, type, year) VALUES ('$title', '$text', '$type', '$year')") or die (mysql_error());

Though I think that might error... haven't tried it myself, as my server's mysql is set as not the strictest setting and thus allows for you to use blanks as your insert ID.
 
Actually, a bit after I posted I realized id wasn't set to auto-increment. I made it primary, set it to auto-increment, and it seems that leaving it "blank" works. Now to get date to automatically timestamp. :(
 
Actually, a bit after I posted I realized id wasn't set to auto-increment. I made it primary, set it to auto-increment, and it seems that leaving it "blank" works. Now to get date to automatically timestamp. :(

Well date isn't set to auto update with the current timestamp in that pic above either, but you can also create your own timestamp using the date and time functions in PHP.
 
With that current setup the date column won't auto-update the timestamp on a row UPDATE call, but it should auto-timestamp itself when you insert a new row. What you're doing however is passing an empty value for the date in your insert statement. Either don't pass a value to the insert statement and let MySQL take care of the timestamping (which is what you seem to want to achieve) or pass something like NOW() as the value instead of an empty string.
 
Haven't had a chance to mess with the timestamp stuff, but I want to password-protect the page I'll be using to post content to the database.

How secure is this code? I want something simple like this, but simple makes me think of vulnerable.

Code:
<?php

// Define your username and password
$username = "someuser";
$password = "somepassword";

if ($_POST['txtUsername'] != $username || $_POST['txtPassword'] != $password) {

?>

<h1>Login</h1>

<form name="form" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    <p><label for="txtUsername">Username:</label>
    <br /><input type="text" title="Enter your Username" name="txtUsername" /></p>

    <p><label for="txtpassword">Password:</label>
    <br /><input type="password" title="Enter your password" name="txtPassword" /></p>

    <p><input type="submit" name="Submit" value="Login" /></p>

</form>

<?php

}
else {

?>

<p>This is the protected page. Your private content goes here.</p>

<?php

}

?>
 
Haven't had a chance to mess with the timestamp stuff, but I want to password-protect the page I'll be using to post content to the database.

How secure is this code? I want something simple like this, but simple makes me think of vulnerable.

That basically should work (didn't heavily look at it but at a glance it looks fine).

The problem you now have though... do you want anyone to be able to view the work or just yourself / those with the pw? You will need to set some sort of "logged in" variable and store it as a session, then check that session for the variable and if its not there, then redirect to the login page.

That script you have will work if your "private stuff here" section includes just like a database entry or something, because it will only work for 1 page load.

Sorry if that doesn't make much sense, trying to write quick before I get back to my regular work hehe ;).
 
No, this login is only to access the page I'll be using to post content. This website is more like a resume/portfolio. Right now (at least) I want anyone to see it. Obviously I don't want anyone but me to insert material.

Another thing. I have a link to that page on my site, but I "hid" it. Or at least it isn't obvious at all. Does that make it any less secure, or should I type it manually every time?
 
No, this login is only to access the page I'll be using to post content. This website is more like a resume/portfolio. Right now (at least) I want anyone to see it. Obviously I don't want anyone but me to insert material.

Another thing. I have a link to that page on my site, but I "hid" it. Or at least it isn't obvious at all. Does that make it any less secure, or should I type it manually every time?

I'd just bookmark it and stick it in another folder that uses a .htaccess file (are you windows or linux based for the server?) to restrict access to it.
 
1&1 uses Linux. I tried that .htaccess thing to customize a 404, but I had some trouble. I think for now I'll use this login thing, but I'll improve things as I go.
 
1&1 uses Linux. I tried that .htaccess thing to customize a 404, but I had some trouble. I think for now I'll use this login thing, but I'll improve things as I go.

Well... you will want to send those as url variables actually, unless you want to use some sort of cookies or stick them on the same page as your other inputs, as passing them twice on the page will remove them as a post variable...

EG:
yoururl.php?name=admin&pass=yourpass (very insecure as people can read this if they can see your browser, or in some other way can capture what is sent.. web logs for instance).

Better:
Username:
Password:
(Rest of your inputs here)

and then copy / paste your mysql stuff inside of the private section in the above page.
 
Here's a seemingly easy task but it's not really working. What I want index.php to do is display some blog entries, the most recent one first. For some reason this code is only displaying one entry, even with two available. I'm not feeling very good about my while statement. I'm sure I'm missing something, but after some tinkering I got it to display something instead of error, which is quite a feat.

The blog table has three fields: id, text, and date (timestamp). I've gotten the id auto-increment and timestamp stuff to work properly now.

Code:
    $query = "SELECT * FROM blog ORDER BY date ASC";
    $result = mysql_query($query);

    while($row = mysql_fetch_assoc($result))
        {
        $entries = "$row[text]";
        }

    echo $entries;
 
Here's a seemingly easy task but it's not really working. What I want index.php to do is display some blog entries, the most recent one first. For some reason this code is only displaying one entry, even with two available. I'm not feeling very good about my while statement. I'm sure I'm missing something, but after some tinkering I got it to display something instead of error, which is quite a feat.

The blog table has three fields: id, text, and date (timestamp). I've gotten the id auto-increment and timestamp stuff to work properly now.

Code:
    $query = "SELECT * FROM blog ORDER BY date ASC";
    $result = mysql_query($query);

    while($row = mysql_fetch_assoc($result))
        {
        $entries = "$row[text]";
        }

    echo $entries;

The problem is that you are overwriting $entries during the loop. Define $entries as an array and use $entries[] in the loop. Or use .= to concatentate instead of overwrite.
 
The problem is that you are overwriting $entries during the loop. Define $entries as an array and use $entries[] in the loop. Or use .= to concatentate instead of overwrite.

Ah. Thanks. Is there a way to have a while loop run a certain number of times? Say I only want three blog entries to display, and after the last one a link to "more entries" appears.


EDIT: Well here's my code now, but all it displays is "Array".

Code:
    $query = "SELECT * FROM blog ORDER BY date ASC";
    $result = mysql_query($query);

    while($row = mysql_fetch_array($result))
        {
        $entries[] = $row[text];
        }

    echo $entries;
 
Code:
    $query = "SELECT * FROM blog ORDER BY date ASC";
    $result = mysql_query($query);

    while($row = mysql_fetch_assoc($result))
        {
        $entries = "$row[text]";
        echo "$entries";
        }

As for the up to 3 thing..

Code:
$counter = 0;
$max_counter = 3;
while (($row = mysql_fetch_assoc($result)) && ($counter < $max_counter)) {
  $counter++;
  // do other stuff
}

Something like that can work, or you can just limit your mysql query as well.

Code:
    $query = "SELECT * FROM blog ORDER BY date ASC LIMIT 3";

There are other ways to do it as well, just depends how you want to :).

You will also want to do some other select to see how many there are total (most likely anyway).
 
print_r($entries);

is how you print arrays/classes btw. although for your case you'd want something like a for loop

foreach($entries as $entry)
{
echo $entry;
}
 
Back
Top