Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
bobthecheese
Jun 7, 2006
Although I've never met Martha Stewart, I'll probably never birth her child.
It's slow and cumbersome, along with having no built-in template acquisition layer (you have to roll your own), but I've always liked PHPTAL as a templating engine.

Maybe that's just because I was exposed to TAL style templating early (thanks, python), but it is one of the few templating languages that makes a proper and decent divide between templates and PHP. It also helps to enforce XHTML compliance because the templates themselves are XML based.

Adbot
ADBOT LOVES YOU

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
Duck, I get that you're trying to limit the amount your designers can do, to avoid them injecting all sorts of horrors directly into the View, but picking a restrictive template system to achieve this isn't the right way to go in my opinion. You either have to learn to trust your co-workers, or you need to run code reviews on stuff they write.

In regards to separating code and display in the templates, I find raw PHP allows for much better separation then Smarty. It's far more readable to a developer on first glance if it's not written like garbage, and a good IDE can actually trace the origin of variables.

For example, if I want to list users, and keep track of the active user:

php:
<?
<table id="myUsers">
<?php
// track active user
$active '';

// List my users
foreach ($users as $user)
{
    // on-the-fly adjustments; I could do this inline, but I like this method as it makes the vars look cleaner in the HTML.
    $name ucwords$user['name'] );
    $birthday date('Y-m-d'$user['birthTimestamp']);
    $active = ($user['active'] ? $user['name'] : $active );

    ?>
        <tr><td><?php echo $name?></td><td><?php echo $birthday?></td></tr>
    <?php
}
?>
</table>
<p>Active User: <?php echo $active?></p>
?>
Compared to smarty:
php:
<?
<table id="myUsers">

{* Track active user *}
{assign var='active' value=''}

{* List my users *}
{foreach from=$users item=user}
    <tr><td>{$user.name|ucwords}</td><td>{$user.birthTimestamp|date_format:'%Y-%m-%d'}</td></tr>
    {if $user.active}
        {assign var='active' value=$user.name}
    {/if}
{/foreach}
</table>
<p>Active User: {$active|ucwords}</p>
?>
We've made multiple systems using Smarty and PHP templates, and I can tell you from experience I'd much rather work with a PHP-based "template" than Smarty any day of the week. I can see your reasons, but I think it's just going to kick your rear end at a later date.

That said, i'm not saying to set a bunch of variables and then include() your template PHP file; I'm still advocating the use of a view layer with segregated variables and the separation of business and view logic, all I'm saying is; don't try to prevent logic in your View and make it impossible to use any kind of PHP, because one day you'll really need it.

duck monster
Dec 15, 2004

I've spend a decade and a half around web design shops and trust me man, theres a reason for that isolation of powers.

Its certainly not unique to templates. Think about private/public variables on classes. Whilst there are some scope and optimization type reasons, frankly
much of its about stopping stupid junior coders from breaking poo poo they don't understand.

We're not even talking about junior programmers, we're talking about an entire industry of arts grads, its that bad. And trust me, I'm an art grad, I should know.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Wait, are you saying that you make all your class members public if you're the only one who's going to be working on a project?

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS

v1nce posted:

Duck, I get that you're trying to limit the amount your designers can do, to avoid them injecting all sorts of horrors directly into the View, but picking a restrictive template system to achieve this isn't the right way to go in my opinion. You either have to learn to trust your co-workers, or you need to run code reviews on stuff they write.

In regards to separating code and display in the templates, I find raw PHP allows for much better separation then Smarty. It's far more readable to a developer on first glance if it's not written like garbage, and a good IDE can actually trace the origin of variables.

For example, if I want to list users, and keep track of the active user:

php:
<?
<table id="myUsers">
<?php
// track active user
$active '';

// List my users
foreach ($users as $user)
{
    // on-the-fly adjustments; I could do this inline, but I like this method as it makes the vars look cleaner in the HTML.
    $name ucwords$user['name'] );
    $birthday date('Y-m-d'$user['birthTimestamp']);
    $active = ($user['active'] ? $user['name'] : $active );

    ?>
        <tr><td><?php echo $name?></td><td><?php echo $birthday?></td></tr>
    <?php
}
?>
</table>
<p>Active User: <?php echo $active?></p>
?>
Compared to smarty:
php:
<?
<table id="myUsers">

{* Track active user *}
{assign var='active' value=''}

{* List my users *}
{foreach from=$users item=user}
    <tr><td>{$user.name|ucwords}</td><td>{$user.birthTimestamp|date_format:'%Y-%m-%d'}</td></tr>
    {if $user.active}
        {assign var='active' value=$user.name}
    {/if}
{/foreach}
</table>
<p>Active User: {$active|ucwords}</p>
?>
We've made multiple systems using Smarty and PHP templates, and I can tell you from experience I'd much rather work with a PHP-based "template" than Smarty any day of the week. I can see your reasons, but I think it's just going to kick your rear end at a later date.

That said, i'm not saying to set a bunch of variables and then include() your template PHP file; I'm still advocating the use of a view layer with segregated variables and the separation of business and view logic, all I'm saying is; don't try to prevent logic in your View and make it impossible to use any kind of PHP, because one day you'll really need it.

tbh, you should be doing your logic in the controller and passing in a fully formed list of users and active users 'cause, you know, separation of concerns and all.

Mister Chief
Jun 6, 2011

I recently reinstalled WAMP and one of my rewrite rules wasn't working properly and after a lot of searching I found that disabling the mod_negotiation module fixed the problem. Can someone explain in layman terms what this module does exactly? It seems that it was specifically the MultiViews option that was causing the problem.

Baby Nanny
Jan 4, 2007
ftw m8.

v1nce posted:

Duck, I get that you're trying to limit the amount your designers can do, to avoid them injecting all sorts of horrors directly into the View, but picking a restrictive template system to achieve this isn't the right way to go in my opinion. You either have to learn to trust your co-workers, or you need to run code reviews on stuff they write.

In regards to separating code and display in the templates, I find raw PHP allows for much better separation then Smarty. It's far more readable to a developer on first glance if it's not written like garbage, and a good IDE can actually trace the origin of variables.

For example, if I want to list users, and keep track of the active user:

php:
<?
<table id="myUsers"><?php// track active user$active '';// List my usersforeach ($users as $user){    // on-the-fly adjustments; I could do this inline, but I like this method as it makes the vars look cleaner in the HTML.    $name ucwords$user['name'] );    $birthday date('Y-m-d'$user['birthTimestamp']);    $active = ($user['active'] ? $user['name'] : $active );    ?>        <tr><td><?php echo $name?></td><td><?php echo $birthday?></td></tr>    <?php}?></table><p>Active User: <?php echo $active?></p>?>

Compared to smarty:
php:
<?
<table id="myUsers">{* Track active user *}{assign var='active' value=''}{* List my users *}{foreach from=$users item=user}    <tr><td>{$user.name|ucwords}</td><td>{$user.birthTimestamp|date_format:'%Y-%m-%d'}</td></tr>    {if $user.active}        {assign var='active' value=$user.name}    {/if}{/foreach}</table><p>Active User: {$active|ucwords}</p>?>

We've made multiple systems using Smarty and PHP templates, and I can tell you from experience I'd much rather work with a PHP-based "template" than Smarty any day of the week. I can see your reasons, but I think it's just going to kick your rear end at a later date.

That said, i'm not saying to set a bunch of variables and then include() your template PHP file; I'm still advocating the use of a view layer with segregated variables and the separation of business and view logic, all I'm saying is; don't try to prevent logic in your View and make it impossible to use any kind of PHP, because one day you'll really need it.

You should just be passing in a filtered data set of active users to your template and looping through that. Not having tons of logic in your templates is a good thing not a bad thing

Golbez
Oct 9, 2002

1 2 3!
If you want to take a shot at me get in line, line
1 2 3!
Baby, I've had all my shots and I'm fine
Memcache vs memcached. From what I read, memcached is the better PHP extension. Unfortunately, it is not supported in Windows, which is what our development machines are. (The servers are Linux).

Should we build a wrapper around it to only use memcached if it's detected, use memcache instead, or just buck up and switch our dev environments to Linux?

I guess the main question here is, does the wrapper idea make sense? It does in my head, simply don't assume memcached is enabled. Note that this is in house and not for redistribution, so we don't need to care about third party stops setups.

McGlockenshire
Dec 16, 2005

GOLLOCKS!

Golbez posted:

Memcache vs memcached. From what I read, memcached is the better PHP extension. Unfortunately, it is not supported in Windows, which is what our development machines are. (The servers are Linux).

Should we build a wrapper around it to only use memcached if it's detected, use memcache instead, or just buck up and switch our dev environments to Linux?

I guess the main question here is, does the wrapper idea make sense? It does in my head, simply don't assume memcached is enabled. Note that this is in house and not for redistribution, so we don't need to care about third party stops setups.

A wrapper might make sense if you want to take advantage of other possible caching mechanisms in the future (shared memory segments, disk-backed caching, APC, etc), or if you need to run on both Windows and Linux at the same time.

Otherwise don't bother.

Golbez
Oct 9, 2002

1 2 3!
If you want to take a shot at me get in line, line
1 2 3!
Baby, I've had all my shots and I'm fine
Hm, thanks. So if we didn't go with a wrapper, what suggestion do you have for our predicament?

Golbez
Oct 9, 2002

1 2 3!
If you want to take a shot at me get in line, line
1 2 3!
Baby, I've had all my shots and I'm fine
Edit: double post

musclecoder
Oct 23, 2006

I'm all about meeting girls. I'm all about meeting guys.

Golbez posted:

Hm, thanks. So if we didn't go with a wrapper, what suggestion do you have for our predicament?

Set up a central Linux box on your local network and have developers use that. It's not ideal, but it's probably faster than everyone switching to Linux.

Baby Nanny
Jan 4, 2007
ftw m8.

Golbez posted:

Hm, thanks. So if we didn't go with a wrapper, what suggestion do you have for our predicament?

Look into something like Vagrant (http://vagrantup.com). You can give each employee a .Vagrantfile that will create a headless VM on your windows machine and mount a local windows folder with the code so you can still have all your devs on windows but run your code on a prod like environment.

duck monster
Dec 15, 2004

Jabor posted:

Wait, are you saying that you make all your class members public if you're the only one who's going to be working on a project?

Chances are if I'm the only one working on it, my language choice wont even support private variables, because there isn't a reason ever not to use python
in a situation where you have a choice 99.99% of the time. And with due respsect to where I am, given a choice on a project language , in 2013 it sure as hell it won't by PHP. Time, and sanity, is money.

edit: Oh god, magic_variables_gpc breaks mysql_escape_string and creates *double slashes* thus rending things MORE insecure.
:negative:
Burn the fields and salt the earths, I need to move this shop to either a good framework, or something not php loving pronto. The "long drop"(poo poo starts at the top and executes through the code to the bottom, then the programmer hangs himself with it in despair) method of web coding needs to die.

edit2: Oh god, I just discovered the boss who's that untrained he doesn't know how functions work codes *on the live server* using an ftp client. I was loving wondering where his copy of the code was. I have so much work to do. :(

duck monster fucked around with this message at 02:42 on May 2, 2013

Good Will Hrunting
Oct 8, 2012

I changed my mind.
I'm not sorry.
I'm working on a project for school where I'm querying a Mongo collection with PHP and getting a result set. I want to create XML to send back to the JS for processing, and I know I can do it with a large chunk of gross repeated code, but I'm wondering how to optimize it. I was thinking something along the lines of:

php:
<?
foreach ($result as $doc) {
    $record = $dom->createElement("Record");

        foreach(key/value pair in $doc){
        // create the key element and text node, append it
        }
        //append record to the XML document
?>
I'm not sure if there's a way to access each [key] => [value] pair within each document. Can I do foreach($doc as $pair) or is that not legal? From my understanding the result pairs are just arrays inside an array so I feel like that should be legal even if I'm not doing it properly.

Good Will Hrunting fucked around with this message at 06:42 on May 2, 2013

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS

Good Will Hrunting posted:

I'm working on a project for school where I'm querying a Mongo collection with PHP and getting a result set. I want to create XML to send back to the JS for processing, and I know I can do it with a large chunk of gross repeated code, but I'm wondering how to optimize it. I was thinking something along the lines of:

php:
<?
foreach ($result as $doc) {
    $record = $dom->createElement("Record");

        foreach(key/value pair in $doc){
        // create the key element and text node, append it
        }
        //append record to the XML document
?>
I'm not sure if there's a way to access each [key] => [value] pair within each document. Can I do foreach($doc as $pair) or is that not legal? From my understanding the result pairs are just arrays inside an array so I feel like that should be legal even if I'm not doing it properly.

The answer is
php:
<?
foreach($doc as $k => $v) { } 
?>
But if you're just outputting data so you can consume it with JavaScript, have you thought about using JSON? If your result set is complete and you just need it in a form you can parse, all you need to do is
php:
<?
json_encode($result)
?>

Good Will Hrunting
Oct 8, 2012

I changed my mind.
I'm not sorry.
Yes, yes I can. And it works wonderfully. Thanks for the help!

Zamujasa
Oct 27, 2010



Bread Liar

duck monster posted:

Chances are if I'm the only one working on it, my language choice wont even support private variables, because there isn't a reason ever not to use python
in a situation where you have a choice 99.99% of the time. And with due respsect to where I am, given a choice on a project language , in 2013 it sure as hell it won't by PHP. Time, and sanity, is money.

edit: Oh god, magic_variables_gpc breaks mysql_escape_string and creates *double slashes* thus rending things MORE insecure.
:negative:
Burn the fields and salt the earths, I need to move this shop to either a good framework, or something not php loving pronto. The "long drop"(poo poo starts at the top and executes through the code to the bottom, then the programmer hangs himself with it in despair) method of web coding needs to die.

edit2: Oh god, I just discovered the boss who's that untrained he doesn't know how functions work codes *on the live server* using an ftp client. I was loving wondering where his copy of the code was. I have so much work to do. :(


duck monster posted:

magic_variables_gpc
:stonk: Why are you using magic_variables_gpc? Jesus Christ write a drop-in replacement using mysqli and even the most basic of prepared queries or something as soon as you can.


(Also, double slashes should theoretically still be fine, as you'd end up going from \' to \\\' (the slashes get escaped too), which is the cause of badly designed websites that output \' instead of ')


duck monster posted:

There is THIS clanger however
PHP code:
		$result = exec("/usr/bin/nslookup ".substr($email, strpos($email, "@")+1), $output); //I dont trust this at all.
		if (!substr_count(implode(",", $output), "NXDOMAIN")) { 
			create_user($email);
...

This is borked. But I need to prove it. I had him leaning over with me fuming about this insane code as I tried to exploit it using stuff like

duckmonster@magicalwebsite.com ; cat /etc/passwd > /var/www/passwds.txt

But nothing I could do could exploit this. Anyone know a good way to DEMONSTRATE that this code is insane and broken to my boss?

Something like "email=pwned@;funexploit" might work (it depends on if you can get away with using spaces)... the fact that it's blindly executing shell parameters without any sort of escaping is an absolute horror, though.

It depends on where $email is coming from. If it's being escaped by PHP's shell arg escape function you might not have much luck.

duck monster
Dec 15, 2004

Zamujasa posted:

:stonk: Why are you using magic_variables_gpc? Jesus Christ write a drop-in replacement using mysqli and even the most basic of prepared queries or something as soon as you can.

This is a massive (Thousands of files) spageti codebase , roughly 12 years worth of monkey patched turds, and the boss insists that it has to stay until its rewritten. Thus I'm not allowed to.

Its loving insanity and I'm going to rewrite the *poo poo* out of it, but its a hell of a task.

peak debt
Mar 11, 2001
b& :(
Nap Ghost
I'm having a bit of a problem with some really simple code.
As in, I have a script like:
code:
<?php

	echo $_GET['test1'] . "<br>";
	echo $_GET['test2'] . "<br>";

?>
Now if you open that script with a arguments like:
http://exar.ch/temp/test.php?test1=x%26quot%3B&test2=x%22

You would expect test2 to be turned into x"
and test1 into x&quot;

However PHP seems to be so "friendly" as to automatically double-decode the test1 variable when it notices a " in it which is causing me no end of problems as it leads to random number of decodes happening on my AJAX data. Is there any way of restricting this behaviour or at least finding out that it happened?

Because I can't just turn the " back into " either, there might be legitimate " in the data like in the test2 variable up there...

Actually in the end my question is:
What does the data passed to the GET variable have to be that it ends up as "&quot;" in PHP?

peak debt fucked around with this message at 01:50 on May 3, 2013

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
Are you sure it's not just the browser rendering " as a double quote? If I run your script on a basic XAMPP install I get browser render of:
code:
x"
x"
However, if I view the source it displays:
code:
x&quot;<br>x"<br>
Which is the expected result.

Edit: Just checked your link; it's the same on your server.

mooky
Jan 14, 2012
I have an htaccess question. I figured this thread would be a good place to start.
I'm using extensionless urls but now want to also support query strings but have them seo friendly.

Here's what I have currently:
code:
RewriteEngine On
RewriteBase /

# Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ $1 [R=301,L]

# Redirect external .php requests to extensionless url
RewriteCond %{THE_REQUEST} ^(.+)\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(.+)\.php$ /$1 [R=301,L]

# Resolve .php file for extensionless php urls
RewriteRule ^([^/.]+)$ /$1.php [L]
This works great, http://domain.com/somefile.php and http://domain.com/somefile/ automatically changes to http://domain.com/somefile
The problem I have is that I want to do http://domain.com/somefile/22 and have it redirect to http://domain.com/somefile.php?id=22
I don't want to limit myself there, I may also want to do http://domain.com/somefile/22/update or something as well which would be http://domain.com/somefile.php?id=22&a=update

I know how to accomplish that without using the above code in my htaccess, I just don't know how to combine them.

Any suggestions or help would be appreciated, if you can point me to a good learning resource or guide, I would also be grateful. I've done a fair amount of googling but keep coming up with the same results which don't help me with my dilemma.

Edit, posted to stackoverflow if you want to reply there and get credit for your answer.

mooky fucked around with this message at 04:25 on May 5, 2013

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
I never have much success googling for mod_rewrite/RewriteRule stuff myself, so someone else might be able to direct you towards learning resources, but here's my take on what you're trying to do.

If you want to convert your url path to query string args, the only way I know to do this is something like the following:
code:
RewriteRule ^([^/]+)/?([^/]*)?/?([^/]*)?/?([^/]*)?/?([^/]*)?/?([^/]*)?$ $1.php?a=$2&b=$3&c=$4&d=$5&e=$6 [QSA,L]
To clarify, the content of the brackets ([^/]*) is getting everything except a slash, while everything with a ? after it is optional. The only thing which needs to be set is the first element ([^/]+). The first element is passed as the php file to use, while everything else is passed as an argument. The QSA directive keeps the query string alive, so if you jam "?myVariable=Value" on the end then this will still be passed to your script.

The problem with this approach is your number of arguments is limited to the number you put in your rule, and the names you assign your variables in htaccess is what you have to deal with in your script. This is less of a problem if you pass the arguments through a dispatcher, but if you're doing that then this approach isn't appropriate anyway.

I'd advocate using a dispatcher which processes the URL passed to it, which gives you far greater control over what's done with that URL. If you come up against something that needs a more advanced, you can modify your dispatcher as appropriate, rather than hacking in more htaccess rules for each special case.

Here's a quick stab at a dispatcher for your current requirement. I've added some notes about using this with procedural code rather than OOP, as I'm guessing your straight-to-file request method is because you aren't using objects to control the execution flow.
code:
# htaccess
RewriteEngine on

# send everything to index.php
RewriteRule (.*) index.php?url=$1 [L,QSA]
php:
<?php
// index.php
// Our dispatcher

class Dispatcher
{
    /**
     * Run the dispatcher using the current URL
     */
    public function Run()
    {
        // url var expected from .htaccess
        $url = (isset($_REQUEST['url']) ? $_REQUEST['url'] : '');
        $this->Dispatch$url );
    }

    /**
     * Dispatch the address passed in $url
     * @param $urlString string
     */
    public function Dispatch$urlString )
    {
        // Extract URL to usable parts
        // parse_url will always return 'path' even if empty.
        $url parse_url($urlString);

        // Split the URL into our arguments.
        // A url of '/' may result in empty array members.
        $args explode('/'$url['path']);

        // and extract the first argument, which is our controller filename
        $controller array_shift($args);

        // If no target given, use default controller
        if (!isset($controller) || empty($controller))
        {
            $controller 'homepage';
        }

        // Clear this scope of vars we don't want anymore in case our code is procedural
        unset($urlString$url);

        if (!file_exists$controller.'.php' ))
        {
            trigger_error('Blah blah blah 404'E_USER_ERROR);
        }

        // Dispatch to controller file
        require( $controller.'.php' );

        // If your controller is procedural, then your code will be executed within the scope
        // of this function.
        // Hopefully your code is NOT procedural and instead class based, with a function
        // like Dispatch() or Run() within each files controller class to execute the code.
        // If it's class based, then the below would try and run your poo poo.

        // Assuming the class name is the same as the filename, make the class and ->Run() it.
        $controllerObject = new $controller;
        $controllerObject->Run$args );
    }
}

// Execute the application
$dispatcher = new Dispatcher;
$dispatcher->Run();

php:
<?php
// beans.php - our controller

class beans
{
    /**
     * Controller dispatcher
     */
    public function Run$args )
    {
        // Don't run if we get passed a "nobeans" query
        if ( !isset($_REQUEST['nobeans']) )
        {
            // Get 'numbeans' from our first URL argument
            $numBeans = (int) ( isset($args['0']) && is_numeric($args['0']) && $args['0'] > $args['0'] : 0);

            // Dispatch
            $this->Beans$numBeans );
        }
    }

    /**
     * Beans
     * @param $x
     */
    protected function Beans$x )
    {
        echo "Yum, i like {$x} beans.";
    }
}

Run the whole thing with a call to "/beans/26" and you'll hopefully see the message. Despite the huge increase of code and complexity, I would call this a much better method than the htaccess method.

v1nce fucked around with this message at 04:01 on May 6, 2013

mooky
Jan 14, 2012

Thanks for the detailed post, I've been considering not using htaccess and instead doing my own php routing / dispatching similar to what wordpress does for content.
Obviously there will be a little htaccess rewrites and a bit of php code to do it but it might be cleaner in the end and handle invalid urls better.

Thanks for your example, If nobody else has a better solution, I might just take this approach. Clearly I'm trying to accomplish the end result of using a framework without have to use and learn one.

Also, if using your example, what would the .htaccess need to look like in order to not route requests for images and such to the dispatcher?

Is this the best way?
code:
RewriteEngine on

# skip css, images and js folders
RewriteCond %{REQUEST_URI} !^/css/
RewriteCond %{REQUEST_URI} !^/images/
RewriteCond %{REQUEST_URI} !^/js/

# send everything to dispatcher.php
RewriteRule (.*) dispatcher.php?url=$1 [L,QSA]

mooky fucked around with this message at 20:02 on May 5, 2013

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
Most people if they have one rule, write it as:

code:
# if it's not a file, and not a directory, send the URL to the dispatcher
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) dispatcher.php?url=$1 [L,QSA]
This setup would let you have routes to /css or /images etc rather than blocking that entire section off from your script, so you could process images for resizing, minify or lessCss if you so desire.

This is fine, but if you have more than one RewriteRule then you may end up writing those conditions over and over for each rule. To get around that, if you know you always want files that exist to be used, you can try out the following:

code:
# If a file or a directory, do nothing (-) and stop processing (L).
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*) - [L]

# Everything else goes to the dispatcher
RewriteRule (.*) dispatcher.php?url=$1 [L,QSA]

mooky
Jan 14, 2012

v1nce posted:

Most people if they have one rule, write it as:

code:
# if it's not a file, and not a directory, send the URL to the dispatcher
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) dispatcher.php?url=$1 [L,QSA]
This setup would let you have routes to /css or /images etc rather than blocking that entire section off from your script, so you could process images for resizing, minify or lessCss if you so desire.

This is fine, but if you have more than one RewriteRule then you may end up writing those conditions over and over for each rule. To get around that, if you know you always want files that exist to be used, you can try out the following:

code:
# If a file or a directory, do nothing (-) and stop processing (L).
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*) - [L]

# Everything else goes to the dispatcher
RewriteRule (.*) dispatcher.php?url=$1 [L,QSA]

So far it is working great, thanks again for all your help!

mooky
Jan 14, 2012
I have traditionally been a procedural guy, I'm trying to do and learn more about OOP as I recognize the benefits and can see that there is greater flexibility and some things are really only possible using OOP. I'm trying to convert my old procedural code to OOP and it's going great but I've hit a little snag that has to do with inheritance and extending classes.

I'm using v1nce's suggested above to do routing of my requests to the related content. I'm also using Smarty which is kind of where my issues are coming from.
I realize there are tons of Frameworks out there, but I don't want to take the time to try different frameworks, learn them and decide on which one I like best and then try and rewrite my code using said framework. I am not a professional programmer or developer, I just really enjoy writing code and PHP is my language of choice.

I'm using the dispatcher class to create the session, connect to the database and do various checks and authentications prior to loading the requested controller.
Once in the controller, i need access to properties and methods in the dispatcher as well as in the controller. From the controller I will instantiate my "pageview" class which instantiates smarty to obviously display my content.
The problem I have is that methods in the pageview class need to access properties in both the dispatcher and controller classes. I'm not sure how to handle this since the controller changes as a different page is loaded so having my pageview class extend the controller doesn't work.

Very quick example of my structure:
php:
<?php
class Dispatcher
{
    var $templates_compile_directory;
    
    function __construct() {
        // In my mind, it makes sense to load config values here.  Maybe I'm wrong...
        $this->templates_compile_directory '/var/www/templates_c';
    }
    /**
     * Run the dispatcher using the current URL
     */
    public function Go()
    {
        // url var expected from .htaccess
        $url = (isset($_REQUEST['url']) ? $_REQUEST['url'] : '');
        $this->Dispatch$url );
    }

    /**
     * Dispatch the address passed in $url
     * @param $urlString string
     */
    public function Dispatch$urlString )
    {
        require( $controller.'.php' );

        $controllerObject = new $controller;
        $controllerObject->Run$args );
    }
}

php:
<?php
// beans.php
class beans extends dispatcher
{
    function __construct() {
        parent::__construct();
    }
    /**
     * Controller dispatcher
     */
    public function Run$args )
    {
        // Don't run if we get passed a "nobeans" query
        if ( !isset($_REQUEST['nobeans']) )
        {
            // Get 'numbeans' from our first URL argument
            $numBeans = (int) ( isset($args['0']) && is_numeric($args['0']) && $args['0'] > $args['0'] : 0);

            // Dispatch
            $this->Beans$numBeans );
        }
    }

    /**
     * Beans
     * @param $x
     */
    protected function Beans$x )
    {
        $page = new page('beans');
        $page->assign('beans',$x); // method doesn't exist in this example, but you see where I'm going...
        $page->template('beans');  // this method sets the template name /templates/beans.tpl
        $page->create();           // this method would load the template and template vars and display the page.
    }
}

php:
<?php
// class.pageview.php
class pageView
{
    private $smarty;
    private $page_name;
    
    function __construct($current_page) {
        $this->page_name $current_page;
        $this->is_smarty_instantiated();
    }
    
    function is_smarty_instantiated() {
        if (is_object($this->smarty)) {
            return true;
        }
    
        return $this->init_smarty();
    }
    
    function init_smarty() {
        require('classes/class.smarty.php');
    
        if (!$this->smarty) {
            $this->smarty = new Smarty();
        }
            
        $this->smarty->caching 0;
        $this->smarty->template_dir '/templates/';
        $this->smarty->compile_dir $dispatcher->templates_compile_directory/* I want to load this property from the dispatcher */
        return true;
    }
}

$dispatcher = new Dispatcher;
$dispatcher->go();

mooky fucked around with this message at 21:43 on May 7, 2013

McGlockenshire
Dec 16, 2005

GOLLOCKS!
You're falling into a bunch of beginner traps here.

Use consistent capitalization and naming. Most in PHP have settled on UpperCamelCase for class names, lowerCamelCase for method names and lower_underscores for properties and variables. You have no consistency here. Just because PHP doesn't care about capitalization here doesn't mean you shouldn't care.

Methods should either be verbs or verbish. You are asking an object (a noun) to do a thing (verb it). Go might be a verb, but it doesn't describe what the method does. Beans isn't a freaking verb.

If your constructor does nothing except for call parent::__construct(), you don't need a constructor in that class. The one provided by the parent will work.

Never ever give methods the same name as their class. Ever. PHP4 considers these consturctors, and PHP5 will fall back to using them if it sees no constructor. Is this the reason for your empty constructor?

Your classes depend on external data in the form of $_REQUEST (in Dispatcher::Go() and beans::run()). This is probably bad, especially when you begin automated testing. Instead of relying on $_REQUEST, pass either it or the specific values into the object at construct time or the method at call time.

Dispatcher::Dispatch() by way of Dispatcher::Go() blindly trusts user input to perform a require. This is a security hole wide enough to drive a train through. You must filter and validate user input.

In pageView (argh fix your naming), your constructor calls is_smarty_instantiated and then discards the output. What's the purpose of the method? All of the functionality can be stashed in the init_smarty method.

Now that we have the simple stuff out of the way,

quote:

The problem I have is that methods in the pageview class need to access properties in both the dispatcher and controller classes.
Your conceptual model is broken.

The controller that gets instantiated by the dispatcher shouldn't give a drat that a dispatcher existed. All it should know is that it exists, and that all of the data it needs has been made available to it.

That controller then should gather all of the data it needs to perform whatever operation it needs to do, perform that operation, and then gather all of the information it needs to provide the user with output.

All of that output should then be sent back to the user somehow. You're choosing to use Smarty. Bad choice, but whatevs. You can do this either directly from within the controller, or by having the controller return the data to the thing that called it (dispatcher), and let it take care of things.

Outside of being passed all of the data it needs in order to do its job, the output rendering bits shouldn't care what instantiated them.

mooky
Jan 14, 2012

McGlockenshire posted:

You're falling into a bunch of beginner traps here.
This may be true, I've never had any formal training and am self taught or learned by examples. I've never officially learned best practices and am trying to retrain myself the right way to do things.

quote:

Use consistent capitalization and naming. Most in PHP have settled on UpperCamelCase for class names, lowerCamelCase for method names and lower_underscores for properties and variables. You have no consistency here. Just because PHP doesn't care about capitalization here doesn't mean you shouldn't care.

Methods should either be verbs or verbish. You are asking an object (a noun) to do a thing (verb it). Go might be a verb, but it doesn't describe what the method does. Beans isn't a freaking verb.
The dispatcher / beans example is from v1nce, I just adopted it. The rest of the example I posted isn't a good representation of my code. I do use consistent capitalization with regards to functions, methods and classes. I may need to work on some of the other stuff, but like I said, I've only ever really coded for myself.

quote:

If your constructor does nothing except for call parent::__construct(), you don't need a constructor in that class. The one provided by the parent will work.
Clearly this is part of my problem, I was trying to make properties available from the parent class. Again, I'm an OOP noob!

quote:

Never ever give methods the same name as their class. Ever. PHP4 considers these consturctors, and PHP5 will fall back to using them if it sees no constructor. Is this the reason for your empty constructor?
I don't use same named functions in classes, it drives me nuts when I see them. I know how to use constructors and destructors, this code snippet was just that, a very very brief representation of my code to try and get things figured out and on the right track.

quote:

Your classes depend on external data in the form of $_REQUEST (in Dispatcher::Go() and beans::run()). This is probably bad, especially when you begin automated testing. Instead of relying on $_REQUEST, pass either it or the specific values into the object at construct time or the method at call time.
Thanks for this, I'll look into that.

quote:

Dispatcher::Dispatch() by way of Dispatcher::Go() blindly trusts user input to perform a require. This is a security hole wide enough to drive a train through. You must filter and validate user input.
I do check if the file exists and don't rely on user input directly for retrieving the file. If the file doesn't exist, a default file is loaded instead.

quote:

In pageView (argh fix your naming), your constructor calls is_smarty_instantiated and then discards the output. What's the purpose of the method? All of the functionality can be stashed in the init_smarty method.
I know you dislike my naming, it was an example... The method is only partially there, it is evaluated in my code to determine if it is true.

quote:

Now that we have the simple stuff out of the way,

Your conceptual model is broken.

The controller that gets instantiated by the dispatcher shouldn't give a drat that a dispatcher existed. All it should know is that it exists, and that all of the data it needs has been made available to it.

That controller then should gather all of the data it needs to perform whatever operation it needs to do, perform that operation, and then gather all of the information it needs to provide the user with output.

All of that output should then be sent back to the user somehow. You're choosing to use Smarty. Bad choice, but whatevs. You can do this either directly from within the controller, or by having the controller return the data to the thing that called it (dispatcher), and let it take care of things.

Outside of being passed all of the data it needs in order to do its job, the output rendering bits shouldn't care what instantiated them.
This is where I am looking for help, from experienced people such as yourself. Instead of just telling me what I am doing wrong, examples of how to do it right would help me on my quest improve my skills.
As for Smarty, I understand it may not be the best, what would you suggest instead?

If I am not to use the Dispatcher to load and store data, instead put that in the Controller, what is the best way to handle multiple controllers needing access to the same information and then calling smarty or some other template engine?

Example:
Home Controller is will need the same set of base configuration information pulled from the database, the session information as well is if the user is logged in or not. This will be true for all controllers. In addition to that, each controller will serve its own purpose and then present data to the user.

mooky fucked around with this message at 00:09 on May 8, 2013

Nebulon Gate
Feb 23, 2013
^^^I want you to read the following books:

PHP and MySQL Web Development
PHP Object Oriented Solutions

When you're done, look into Laravel, and then read:

Laravel: Code Happy

And read their supplied documentation.

McGlockenshire
Dec 16, 2005

GOLLOCKS!
Oh, crap.

Sorry, somehow I misinterpreted "new to OOP" as "new to MVC" and... yeah.

I'll come back tomorrow afternoon with some more concrete recommendations.

Personally, I advise avoiding most frameworks until you're more comfortable with OOP and MVC. One of the best way to grow to appreciate a framework is to do all the hard work yourself first and discover how much of a royal pain in the rear end the standard request lifecycle can be.

Also, do keep in mind that OOP isn't the be-all and end-all of development. Some of the best code I've ever worked with has been an OOP backend glued together using good old procedural bits.

mooky
Jan 14, 2012

McGlockenshire posted:

Oh, crap.

Sorry, somehow I misinterpreted "new to OOP" as "new to MVC" and... yeah.

I'll come back tomorrow afternoon with some more concrete recommendations.

Personally, I advise avoiding most frameworks until you're more comfortable with OOP and MVC. One of the best way to grow to appreciate a framework is to do all the hard work yourself first and discover how much of a royal pain in the rear end the standard request lifecycle can be.

Also, do keep in mind that OOP isn't the be-all and end-all of development. Some of the best code I've ever worked with has been an OOP backend glued together using good old procedural bits.

I have a tendency to over-think and over-complicate things. I've been trying to wrap my mind around a complete OOP approach when really a mix of procedural and OOP is probably my best bet.
I prefer to get my hands dirty and do not want to use a Framework. My primary reason for using Smarty for templates is because its familiar to me. I'm hesitant but not opposed to learning a new Template engine. Twig looks good but it looks like it may have a learning curve to it.

I'm going to rethink my approach and look forward to your suggestions tomorrow! Thanks again!

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
These guys have pretty good points. My code example was more geared towards your exact problem at the time; I'm not sure I'd recommend it as a starting point for a new framework.
The irony always is, by the time you've rolled your own and figured out the problems you've made for yourself, you could have learned to use an existing framework (CakePHP, Laravel, CodeIgnighter, Zend, etc). If you're going to deploy something that's not just a personal piece, always go with a framework.

That's not to say rolling your own isn't a great learning exercise; If you're still getting a feel for PHP and OOP (or code in general) then it's almost a rite of passage. It's also a lot more interesting when you want to know how things work from front to back, rather than just tacking things onto the black box that are other frameworks.

Apologies for my naming conventions in the sample code, I could have been a lot more helpful with that but it was just a quick half hour job, McGlockenshire makes a lot of good points.

You'll want to watch out for Beans::Run as this is basically just a sub-dispatcher which then calls your desired action. I'd recommend modifying the Dispatcher itself to call the function directly after checking if it exists (see method_exists), which would add another layer of safety to the dispatcher; if it's not a file, with the class, with the action, bail out with a 404. Again, still a big security hole there, but it depends on the structure of your framework.

You also don't need to have Beans be an extension of Dispatcher. If you're after the variables from Dispatcher, find a different way to do it. Passing all the functionality from Dispatcher onto Beans is a bit crazy just for one variable. Dispatcher shouldn't be a place for initialising config variables either; it's a tool the system uses and nothing more.

Most frameworks would solve this problem by having a Configure/Registry class which contains a whole ton of variables you'll want to get at in a variety of places. This class would be static and you'd call variables by doing poo poo like Configure::get('smarty_template_path');. Some of the more recent frameworks don't use statics and instead pass the config around as something which is available inside the view/controller ($this->configure->get('smarty_blah');), but that's a lot more complicated if you're just learning, and it's better to stick with the static class.

Finally, having a pageView class is a nice move; if you scrap smarty it'll be easier to replace if you've got it segregated like this. Don't call the Dispatcher at the end of this classes code though, my example had it in the index.php only for my own convenience. Instead consider restructuring your code something like the following:

code:
/index.php
/libs/disaptcher.php
/libs/pageview.php
/controllers/beans.php
where index.php contains:
php:
<?php
// index.php - Bootstrap file

// Load libraries
require_once('libs/dispatcher.php');
require_once('libs/pageview.php');

// Run dispatcher
$dispatcher = new Dispatcher();
$dispatcher->go();

Having controllers inside a controllers directory will help mitigate the security hole too, as you'll modify your code to only load files that are in the controllers directory. You'll still need more sanity checks, but it's a good start.

Winter is Coming might be right though; a few books won't hurt.

mooky
Jan 14, 2012

v1nce posted:

These guys have pretty good points. My code example was more geared towards your exact problem at the time; I'm not sure I'd recommend it as a starting point for a new framework.
The irony always is, by the time you've rolled your own and figured out the problems you've made for yourself, you could have learned to use an existing framework (CakePHP, Laravel, CodeIgnighter, Zend, etc). If you're going to deploy something that's not just a personal piece, always go with a framework.

That's not to say rolling your own isn't a great learning exercise; If you're still getting a feel for PHP and OOP (or code in general) then it's almost a rite of passage. It's also a lot more interesting when you want to know how things work from front to back, rather than just tacking things onto the black box that are other frameworks.

Apologies for my naming conventions in the sample code, I could have been a lot more helpful with that but it was just a quick half hour job, McGlockenshire makes a lot of good points.

You'll want to watch out for Beans::Run as this is basically just a sub-dispatcher which then calls your desired action. I'd recommend modifying the Dispatcher itself to call the function directly after checking if it exists (see method_exists), which would add another layer of safety to the dispatcher; if it's not a file, with the class, with the action, bail out with a 404. Again, still a big security hole there, but it depends on the structure of your framework.

You also don't need to have Beans be an extension of Dispatcher. If you're after the variables from Dispatcher, find a different way to do it. Passing all the functionality from Dispatcher onto Beans is a bit crazy just for one variable. Dispatcher shouldn't be a place for initialising config variables either; it's a tool the system uses and nothing more.

Most frameworks would solve this problem by having a Configure/Registry class which contains a whole ton of variables you'll want to get at in a variety of places. This class would be static and you'd call variables by doing poo poo like Configure::get('smarty_template_path');. Some of the more recent frameworks don't use statics and instead pass the config around as something which is available inside the view/controller ($this->configure->get('smarty_blah');), but that's a lot more complicated if you're just learning, and it's better to stick with the static class.

Finally, having a pageView class is a nice move; if you scrap smarty it'll be easier to replace if you've got it segregated like this. Don't call the Dispatcher at the end of this classes code though, my example had it in the index.php only for my own convenience. Instead consider restructuring your code something like the following:

code:
/index.php
/libs/disaptcher.php
/libs/pageview.php
/controllers/beans.php
where index.php contains:
php:
<?php
// index.php - Bootstrap file

// Load libraries
require_once('libs/dispatcher.php');
require_once('libs/pageview.php');

// Run dispatcher
$dispatcher = new Dispatcher();
$dispatcher->go();

Having controllers inside a controllers directory will help mitigate the security hole too, as you'll modify your code to only load files that are in the controllers directory. You'll still need more sanity checks, but it's a good start.

Winter is Coming might be right though; a few books won't hurt.

My example was poo poo, I cut out a bunch of code to keep thing short and its biting me in the rear end.
I really don't want to use a framework, personal preference. I just prefer to build things myself, even if I am reinventing the wheel.
I've read a couple of books regarding OOP, nothing beats real world experience and this is the first chance I've had to really build something from scratch.

I'm aware of the security implications of using user input to include files. The controllers are in a controllers directory and I'll make sure to do more sanity checking prior to loading the files.
I'm going to go back to the dispatcher serving the single purpose and handle everything else in the controllers.

I realize my mistake with the extension of dispatcher and won't be doing that either, it was the wrong way to solve a problem I shouldn't have had to begin with.

Thanks again for your help and comments!

duck monster
Dec 15, 2004

Whats the current thinking around these woods on railsy type frameworks for php.

I'm wanting to rewrite a very loving insane php app I've had shat upon my lap. Its loving huge, and its a mess of bad security, embedded html (with table layouts and < font> tags and poo poo, its a horror) , and almost no concept of structured design. It has to all be burnt to the ground, its that bad.

So looking around, I need something that'll work well with an *existing* database, has templates (or at least a php view system I can teach a retarded dreamweaver wrangler how to use in under half an hour) , a decent selection of modules and if possible database migrations. And no php 5.4 because the existing codebase is loving terrible and relies on now deprecated features, and I need to co-pilot the system across.

So Cake. Seems good, but uh, its kinda bulky and crufty looking.
Code igniter looks neat, but I sure do see a lot of people claiming its redundant on the net.
Laraval... Looks neat, but its also a bit huge looking and I dont know how well supported it is.

What else is there. Learning curve is important! If I had my way I'd do it in Django, but I'm not sure the boss (who insists on hacking this himself too) wants to learn a new language, even though python is actually amazingly easy.

Calyn
Sep 3, 2011

duck monster posted:

So Cake. Seems good, but uh, its kinda bulky and crufty looking.
Code igniter looks neat, but I sure do see a lot of people claiming its redundant on the net.
Laraval... Looks neat, but its also a bit huge looking and I dont know how well supported it is.

What else is there. Learning curve is important! If I had my way I'd do it in Django, but I'm not sure the boss (who insists on hacking this himself too) wants to learn a new language, even though python is actually amazingly easy.

I've had to do a similar rewrite very recently and went with Symfony2. The latest versions require PHP 5.3.x, it uses Twig for templating which is just awesome and easy to pick up, and has a feature to create entities and a CRUD from an existing database (although I can't say how useful the result will be for you, it did save me some time though). The documentation is pretty good, just the community support can be a little lackluster (mainly via IRC, forums are not active enough,.... or stackoverflow of course). So far I've found well-supported bundles for several things I needed like user management, image processing, etc. Don't really know how it compares to the other frameworks you listed, but it's worth a look.

mooky
Jan 14, 2012
Ok, so I decided to give it some thought and opened my mind to the concept of learning a framework to save myself some time.
I have this really great idea that I am finally trying to create and don't want to have any regrets later and have to redo or rewrite things.
I skimmed this thread and have found that Laravel and Symfony 2 seem to be the favorites. I downloaded the Symfony book and and have been running through the excersizes and so far I like what I'm seeing.

I have no idea what Doctrine is, and I don't like the example they used in the beginning of the book with the blog posts, this doesn't make sense to me:

php:
<?
public function listAction()
{
    $posts = $this->get('doctrine')->getManager()
        ->createQuery('SELECT p FROM AcmeBlogBundle:Post p')
        ->execute();
    return $this->render(
        'AcmeBlogBundle:Blog:list.html.php',
        array('posts' => $posts)
    );
}
?>
I understand it's making a database call using doctrine, I'm not sure what getManager() is and it isn't clear to me based on the example if in the query, "SELECT p FROM AcmeBlogBundle:Post p" where 'p' comes from and what is AcmeBlogBundle:Post?

This makes more sense to me from my obvious procedural PHP background:

php:
<?
function list_action()
{
    $posts = get_all_posts();
    require 'templates/list.php';
}

function get_all_posts()
{
    $link = open_database_connection();
    $result = mysql_query('SELECT id, title FROM post', $link);
    $posts = array();
    while ($row = mysql_fetch_assoc($result)) {
        $posts[] = $row;
    }
    close_database_connection($link);
    return $posts;
}
?>
I'm still reading through the book, is there direct mysql support via pdo or something as opposed to now having to learn doctrine? Should I stop reading about Symfony and check out Laravel?
So far I like it, I'm not thrilled about this doctrine thing, but everything else looks fairly straight forward and I can see myself using it.

musclecoder
Oct 23, 2006

I'm all about meeting girls. I'm all about meeting guys.
Quick Overview: Doctrine is an ORM - Object Relational Manager. It manages (hence the getManager()) the objects (it calls them entities) and their relations in your database.

In the example there, it actually used DQL - Doctrine Query Language - which gets translated to raw SQL which gets executed and the results are returned. In that example, 'p' is just an alias to the entity Post (which most likely maps to a table named 'posts' or 'post').

Doctrine is big and complex and sometimes slow. I would not recommend it for beginners. The only issue is that it and Symfony2 are kind of in bed together to begin with.

Calyn
Sep 3, 2011

mooky posted:

I have no idea what Doctrine is, and I don't like the example they used in the beginning of the book with the blog posts, this doesn't make sense to me:

First off, there is another decent tutorial for Symfony2 here that goes through the basic things in a more step-by-step basis: http://www.ens.ro/2012/03/21/jobeet-tutorial-with-symfony2/
Maybe that helps.

Doctrine is the default database library for Symfony2. You CAN use another one such as Propel instead, or don't use either and do it all manually.
Doctrine however has the advantage of taking care of all the persistence between your entities and the db. I'd definitely spend the time to get used to it. It also has its own documentation btw: http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/index.html

quote:

I understand it's making a database call using doctrine, I'm not sure what getManager() is and it isn't clear to me based on the example if in the query, "SELECT p FROM AcmeBlogBundle:Post p" where 'p' comes from and what is AcmeBlogBundle:Post?

The manager is simply doctrine's class responsible for persisting your entities and getting them from the repository/database, using DQL (Doctrine Query Language).

AcmeBlogBundle:Post is your Post entity, p is its alias that you have defined in the query. As SQL that would be like 'SELECT * FROM posts AS p' (if your Post entity is mapped to a "posts" table).

I suggest you read up on the links I gave above, at the least follow that tutorial. Doctrine is very powerful once you get used to it, but you CAN choose to ignore it. (please don't) ;)

edit: beaten :(

Calyn fucked around with this message at 19:17 on May 8, 2013

Adbot
ADBOT LOVES YOU

mooky
Jan 14, 2012

Calyn posted:

First off, there is another decent tutorial for Symfony2 here that goes through the basic things in a more step-by-step basis: http://www.ens.ro/2012/03/21/jobeet-tutorial-with-symfony2/
Maybe that helps.
Amazing!!! This is most helpful!

musclecoder posted:

Quick Overview: Doctrine is an ORM - Object Relational Manager. [...]

Doctrine is big and complex and sometimes slow. I would not recommend it for beginners. The only issue is that it and Symfony2 are kind of in bed together to begin with.

Calyn posted:

Doctrine is very powerful once you get used to it, but you CAN choose to ignore it. (please don't) ;)

Well, if its complex and slow and I can use PDO or the mysql_ functions (OMG, I KNOW!), why should I spend the time to learn Doctrine? I don't want to take the time to learn something that I won't use all the time. I may use it for this project, but what about projects that I don't build with a Framework? It just seems like an extra step, or complication that I don't need right now.

What real benefit does Doctrine offer over traditional methods for accessing a MySQL database? Anything that really really justifies learning Doctrine?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply