Subject Re: [firebird-php] Jumping in the wagon
Author Jochem Maas
[PS: can't this frakking list do plaintext???]

Alan McDonald wrote:
>
>
>> I couldn't resist commenting on the example. sorry if the
>> critique seems harsh.
>
> By all means
>
>>
>>
>> > Here's a typical (short) example. It takes full advantage
>> of the data
>> > abstraction but I'm also not shy on performing direct data
>> actions via
>> > the base functions of php/ibase.
>>
>> using DA and the 'raw functions' intermittently inside a
>> single project seems inconsequential to say the least.
>
> Not sure what your observation here is

mixing the use of data abstraction layer and ibase_* directly

...

>> you generally output HTML before running logic/doing
>> queries/etc? that is yuck imho.
>
> I see no problem with it. I use page buffering sometimes in the same why I
> use try exception blocks, so I can catch exceptions and redirect or place
> html in response.

> "yuck" sounds like a personal thing anyway.. :-)

probably - but if your hammering on about performance (millisecond this and that)
then I'd say using output buffers to 'fix' such things is the wrong solution.

>
>>
>> > <?php
>> > include "version.php";
>> > include_once "ezfirebird/ez_sql.php";
>> > include_once "ez_resultsmcs.php";
>> > include "metatags.php";
>> > ?>
>> > <title>Account Browser</title>
>> > <script language="JavaScript">
>>
>> this is more correct, also there should be html comments (or
>> better yet an HTML comments CDATA declaration) to hide the JS
>> from old/shite
>> browsers:
>
> In this instance it's a coporate environment - no such browsers exist. But
> if you've looked at recent stats of browser use, there are not many "shite"
> browsers around anymore anyway.

I see no extra cost in writing valid (x)HTML regardless of the environment
with the added bonus of being more future proof.

>
>>
>> <script type="text/javascript">
>> /* <![CDATA[ */
>>
>> function bla() {}
>>
>> /* ]]> */
>> </script>
> ....
>> > <?php
>> > // Submission Actions
>> > ----------------------------------------------------------
>> > if (($_POST['toggledns']=="ok")&&($_POST['accountid']!=null)) {
>> > $toggleid = $db->get_var("SELECT O_UPDATE FROM
>> > TGL_DNS(".$_POST['accountid'].",'T')");
>> > $_GET['BRSR']=$_POST['BRSR'];
>> > $_GET['f']=$_POST['f'];
>> > $_GET['alpha']=$_POST['alpha'];
>> > }
>> > // Data extraction
>> > ----------------------------------------------------------
>> > ---
>> > $db_table_name ="ACCOUNT";
>> > $db_table_fields ="ID, ACCOUNT, DESCRIPTION, "; $db_table_fields
>> > .="(SELECT COUNT(*) FROM CONTACT WHERE
>> > CONTACT.FK_ACCOUNT=ACCOUNT.ID) AS CONTS, ";
>> > $db_table_fields .="(SELECT ADDRESS1 FROM ADDRESS WHERE
>>
>> ...
>>
>> > $db_table_where ="WHERE FK_SECCODE=".$_COOKIE['FK_SECCODE'];
>> > $alphacode = "";
>>
>> all the above can be done in a single string which would make
>> it more readable.
>
> I think this is very much personal taste as to what's more readable. When
> you start manipulating where and order by clauses according to input
> variables, one string isn’t going to do it anyway.

my own example verifies that. it's the endless concatenation I was referring to.

> Your example is one string but it's line broken to make it readable - what's
> the real difference?

it's spread over many lines on purpose to make it readable but there are no
quotes and semicolons all the way through. I agree though that comfort level
is a matter of personal taste and what you are used to using.

I prefer :

$sql = "SELECT foo
FROM foobar";

to:

$sql = "SELECT foo";
$sql .= "FROM foobar";

the single string is also a millisecond or so faster ;-)


...

>>
>> defining functions halfway down a script rather than at the
>> top/bottom or preferably in a seperate file is maintainable?
>
> Absolutely! Since these are functions used by the layout class, they use
> column number identifiers from the query above so the layout of the query
> makes it easy to count the field/column positions.
> Remember, there are over a hundred pages in this project with the exact same
> layout - you can jump directly to the same part in the page... It's so
> reliable.

I would say it's broken by design if it's repeated in 100's of files.
my simpleTable() function does pretty much the same thing ... all the display
logic is blackboxed into a single function and reused in lots of places.

but granted maintainability is, to a lesser or greater degree, defined by the guy that
has to do the maintaining.

>
>>
>> > if ( !empty($C6) ) { // Address Line 2
>> > $C6 = $C6.'<br>';
>> > }
>> > if ($C4>1) {
>> > $C4 = "<img src='images/users.gif' WIDTH='16' HEIGHT='16' BORDER=0
>> > ALIGN='MIDDLE' ALT='Multiple Contacts'> ".$C4; } else {
>> > $C4 = "<img src='images/user.gif' WIDTH='16' HEIGHT='16' BORDER=0
>> > ALIGN='MIDDLE' ALT='1 Contact'> ".$C4;
>> > }
>> > $C13 = $C13+$C14;
>> > $C12 = "<b>P:</b> ".$C12."<br><b>F:</b> ".$C17;
>> > $C18 = ($C18=='T'?"<a href=javascript:toggledns(".$id.",true);><img
>> > src='images/error.gif' WIDTH='16' HEIGHT='16' BORDER=0
>> ALIGN='MIDDLE'
>> > ALT='DNS\r\nToggle:Do Not Solicit'></a>":"<a
>> > href=javascript:toggledns(".$id.",false);><img src='images/tick.gif'
>> > WIDTH='16' HEIGHT='16' BORDER=0 ALIGN='MIDDLE'
>> ALT='Active\r\nToggle:Do Not
>> > Solicit'></a>");
>> > }
>> > // $db->vardump($ezr);
>> >
>>
>> ...
>>
>> > ?>
>> > <p><font face="tahoma" size="1"><b>Notes:</b>
>> > <br>Click Account Name to edit/add contacts for the account.
>> > <br>Numbers in brackets are contacts for this account.
>> > <br><a href="accountnew.php">Click here</a> to add new account.
>> > </font></p></br>
>> > </form>
>> > </body>
>>
>> I guess XHTML is not your thing ;-)
>
> Generally not and not in this project. Do I really need it? Will it do this
> job 300 millseconds faster?

will it do it any slower? no - it is more future proof, additionally using CSS instead of
inline FONT tags and the like is more manageable and allows much greater visual output
consistency at no extra cost.

>
> I could live with your code too. It's not much different in my opinion. You
> may disagree.

I think I could live with your code - but looking at it I wouldn't want to, I'd argue
that makes mine somewhat more approachable for someone who is not familiar with it,
well 'argue' is a strong word, 'hope' is more appropriate.

I don't expect new maintainers of my code to like it but I do try to write stuff that
thirdparties will be able to look at and quickly grok it without hurting their eyes
... I've probably failed in this respect more times than I have succeeded :-)

... before this becomes a pissing contest I'll concede that the differences are not
that great :-)

> E.g.
> $Page->showFooter();
> And
> <?php include "footer.php";?>

no real difference here - if we discount global scope pollution and the point
at which the output is done. personally I try to follow a [semi-]fixed order of doing
things in simple pages like these:


1. init app / include page specific funcs /etc (auto_prepend_file is often my friend)
2. grab/clean input variables
3. do some logic
4. grab data / do queries
5. output page


> or even
> <?php include "footer.htm";?>
>
> Any real benefits? Are there milliseconds invoiced here?

what is with all these milliseconds? I wasn't arguing OO over
procedural includes in this case although I do think that encapsulating
stuff in functions/classes is generally preferable to an include, in the
global scope, that generates output because you minimize the chance of
variable pollution, conversely I don't like it, generally, when an included
file relies on variables defined in the including file.

although I'd take maintainability over performance any day of the week ...
not to say I'd be content to deliver something that was slow as molasses but
bigger iron is always cheaper than increased developer maintainance time.

>
> Alan
>
>>
>> >
>> > </html>
>>
>>
>> <?php
>> /**
>> * list.php :: list all employees!
>> *
>> * @author Jochem Maas <jochem@...
> <mailto:jochem%40iamjochem.com>>
>> * @copyright Copyright 2006, beeldspraak
>> * @link http://beeldspraak.com <http://beeldspraak.com>
>> */
>>
>> // ordering
>> $oSessVar = array('employee', 'o');
>> $dSessVar = array('employee', 'd');
>>
>> MSess::initVar($oSessVar, 'login');
>> MSess::initVar($dSessVar, 'ASC');
>>
>> $oCur = MSess::getVar($oSessVar);
>> $oNew = getG('o');
>> $oChk = $oNew ? $oNew : $oCur;
>> if ($oNew == $oCur) {
>> $dCur = MSess::getVar($dSessVar);
>> $oDir = ($dCur == 'ASC') ? 'DESC' : 'ASC';
>> } else {
>> $oDir = $oNew ? 'ASC' : MSess::getVar($dSessVar);
>> }
>>
>> $oOpts= array('id' => 'id','name' => 'full name','active' =>
>> 'active','login' => 'login');
>> switch ($oChk) {
>> case 'id':
>> $orderby = 'id '.$oDir;
>> break;
>> case 'name':
>> $orderby = 'fullname '.$oDir;
>> break;
>> case 'active':
>> $orderby = 'active DESC, name '.$oDir;
>> break;
>> case 'login':
>> default:
>> $orderby = 'name '.$oDir;
>> break;
>>
>> }
>> MSess::setVar($oSessVar, $oChk);
>> MSess::setVar($dSessVar, $oDir);
>>
>> // filtering?
>>
>> // do the query
>> $qry = "SELECT e.id, e.name, e.fullname, e.empcode, e.email,
>> e.active, e.level, e.is_admin,
>> ( SELECT (
>> SUM(h.monday) +
>> SUM(h.tuesday) +
>> SUM(h.wednesday) +
>> SUM(h.thursday) +
>> SUM(h.friday) +
>> SUM(h.saturday) +
>> SUM(h.sunday)
>> ) FROM hours h WHERE h.employee_id=e.id
>> ) AS hours_total
>> FROM employees e
>> ORDER BY $orderby";
>>
>> $res = $MDB->query($qry);
>> $rows = $MDB->fetchrowset($res);
>>
>> // create funky hour percentage field
>> $totalhours = 0;
>> foreach ($rows as $row) $totalhours +=
>> floatval($row['hours_total']);
>> $hours_1pc = $totalhours / 100;
>> foreach ($rows as $k => $row) $rows[$k]['hours_pc'] =
>> $hours_1pc ? number_format(($row['hours_total'] / $hours_1pc), 2, '.',
>> '').' %' : '0 %';
>>
>> // define column names for output
>> $cols = array('id',
>> 'login',
>> 'full name',
>> 'trigram',
>> 'email address',
>> 'active',
>> 'auth level',
>> 'intranet admin',
>> 'hours total',
>> 'hours %');
>>
>> // header
>> $Page->showHeader("Employees List");
>>
>> echo '
>> <p>
>> <form method="get">
>> Order by: ',selectTag($oOpts, $oChk, 'o', 0,
>> 'this.form.submit();'),'
>>   <input value="'.($oDir ==
>> 'ASC'?'â–¼':'â–²').'" type="submit"/>
>> <form>
>> <br /><br />
>> </p>
>> ';
>>
>> if (!$res) {
>> echo "<p>query failure!</p>";
>> } else if ($MDB->numrows($res) == 0) {
>> echo "<p>no employees found! (adjust your filter if
>> necessary.)</p>";
>> } else {
>> simpleTable($rows, $cols, true,
>> array('field' => 'id', 'urltpl' =>
>> '/employees/edit.php?'.POST_ID_URL.'=%s'),
>> array('field' => 'id', 'urltpl' =>
>> '/employees/delete.php?'.POST_ID_URL.'=%s'),
>> array('active', 'is_admin'),
>> false,
>> array('level', 'hours_total', 'hours_pc'));
>> }
>>
>> // footer
>> $Page->showFooter();
>>