I would call that bad just for using the id "question1" on the answer. The ID should say what it is. the LABEL is the question, not the input.
If you have a whole bunch of them automated, you may have to resort to numbers just to keep the back-end code simple; in that case it's not entirely about clearly naming for the purpose of maintaining the HTML, it's about building sane PHP.
though at that point, you'd be building the ID with PHP, which you are not.
Oh, and I'd suggest htmlspecialchars instead of htmlentities there -- no sense wasting bandwidth on entities you don't need to escape.
Besides, if you're going to have a bunch of them in a row, all taking the same error checks and using the same markup, they'd be in an array letting you quite easily set a meaningful key.
Code:
$questionnaire=array(
'whyStartBusiness' => '1) Why did you decide to start your own business?',
'whatNotToDo' => '2) What do you think should not be done when starting a business?',
'whatToDo' => '3) What advice do you have for starting a business?'
);
foreach ($questionnaire as $key => $question) {
echo '
<label for="',$key,'">',$question,'</label>
<textarea
id="',$key,'"
name="answer[',$key,']"
cols="40" rows="8"
>',(
isset($_POST['answer'][$key]) ? htmlspecialchars($_POST['answer'][$key]) : ''
),'</textarea>
',(
empty($errors[$key]) ? '' : '<span class="error">'.$errors[$key].'</span>'
),'<br />';
}
Your validation checks could work against them the same way. It also would mean having a list of keys to check against, so people can't just willy-nilly fake their own keys to trick your form into doing something it shouldn't. (a danger using array-type NAME attributes).
Oh, I assumed your $answer array was pulled from $_POST for resending the form if they enter it wrong -- at which point why the extra array for the same values? Also, notice I'd swing an axe at the extra <?php ?> for nothing... that's just sloppy coding IMHO.
Bookmarks