Page 1 of 2 12 LastLast
Results 1 to 40 of 52
  1. #1
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416

    Comparing PHP, Python (and maybe Ruby, Java too)

    This thread is intended to contain a collection of examples coded up in PHP and Python - hoping that some Ruby and Java folks will join in. We're carrying on from another thread ("which is better asp or php?") because the original premise of that thread was off-base (although popular - 92 posts, 1,058 views over a short period of time). A better question is "what are the differences between X, Y, and Z?".

    In the spirit of this thread, we are not here to argue about language implementations but highlight the differences and similarities -- perhaps as we do that, conclusions will come easily to us all and the many silent lurkers following such threads.

    First off, lets decide on some basic ground rules and determine the sorts of examples we'll show off.

    Ground Rules:

    1. The purpose of this is to illustrate language differences and similarities, not external library implementations. Therefore wherever possible we'll construct scenarios for implementation that can be addressed by the language's standard features and library.

    2. We'll look at basics and progress from there including looking at basic data types, flow control, error handling, sorting, database access. Later on we might want to look at common current topics such as XML handling or JSON.

    3. A short specification detailing what's required out of the solution (very short... a few lines at most) will help us keep on the right track.

    4. Once a reference implementation is done in a language, authors are welcome to point out where commonly used libraries might further empower a programmer. While we are trying to show off language differences, it would be good for the greater community at large to see what "real world" decisions have as an impact.

    We're inventing this as we go. Bear with us.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  2. #2
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    We should start... at the start: data types. No spec for this one, lets just compare data types in Python and PHP.

    1. Basic Types - String, Integer, Float, Boolean, None / NULL
    2. Complex Types - Dictionary (PHP's Array), List, Tuple. We'll deal with objects later.

    PYTHON

    Incidentally, throughout my examples I'm going to be pasting the actual output of a Python interpreter - which comes with Python. The interpreter shell is a very handy tool when learning the language. I highly recommend installing "pyrepl" http://codespeak.net/pyrepl/ - it will give you another method of accessing the shell (command is "pythoni" instead of "python") that adds the ability to edit multi-line commands more easily in the shell, but perhaps most importantly, tab-completion. Remember, the shell is for proving things out... we don't edit all our code in it!

    1. Basic Types
    Code:
    foo = "A string"
    Strings are immutable in Python. Strings are also full-on objects in their own right - well, basically everything in Python is an object. Thus foo has a number of methods:
    Code:
    ->> foo = 'A string'
    ->> foo.title()
    'A String'
    ->> foo.upper()
    'A STRING'
    ->> foo.replace('A', 'My')
    'My string'
    What are all the methods and properties? We don't have to go look up documentation; with pyrepl installed in our interpreter, simply type the object name, a period, some or none of the method or attr names and press tab (cut below for brevity) to see the list:list
    Code:
    [ foo.capitalize       ][ foo.center           ][ foo.count            ][ foo.decode           ]
    [ foo.encode           ][ foo.endswith         ][ foo.expandtabs       ][ foo.find             ]
    [ foo.index            ][ foo.isalnum          ][ foo.isalpha          ][ foo.isdigit          ]
    [ foo.islower          ][ foo.isspace          ][ foo.istitle          ][ foo.isupper          ]
    [ foo.join             ][ foo.ljust            ][ foo.lower            ][ foo.lstrip           ]
    [ foo.partition        ][ foo.replace          ][ foo.rfind            ][ foo.rindex           ]
    [ foo.rjust            ][ foo.rpartition       ][ foo.rsplit           ][ foo.rstrip           ]
    [ foo.split            ][ foo.splitlines       ][ foo.startswith       ][ foo.strip            ]
    [ foo.swapcase         ][ foo.title            ][ foo.translate        ][ foo.upper            ]
    [ foo.zfill            ]
    ->> foo.
    Want to know what a method expects and returns?
    Code:
    ->> help(foo.startswith)
    Help on built-in function startswith:
    
    startswith(...)
        S.startswith(prefix[, start[, end]]) -> bool
        
        Return True if S starts with the specified prefix, False otherwise.
        With optional start, test S beginning at that position.
        With optional end, stop comparing S at that position.
        prefix can also be a tuple of strings to try.
    Other basic types - Integers, booleans, floats are also objects with their own methods and properties.

    2. Complex Types

    Dicts / Dictionaries (PHP's Array)

    A dict is very similar to a PHP Array - its an ordered mapping. Keys point to values; there are no practical restrictions on values; keys must be immutable and hashable. You'll commonly find integers and strings as keys.

    Code:
    ages = {'Marty' : 12, 'June' : 15, 'Harry' : 10}
    And like everything else in Python, a dict is an object:
    Code:
    ->> ages.keys()
    ['Marty', 'June', 'Harry']
    ->> ages.values()
    [12, 15, 10]
    ->> ages.items()
    [('Marty', 12), ('June', 15), ('Harry', 10)]
    LISTS

    Lists are sequences; lists are mutable; sequences do not have to contain homogenous data.
    Code:
    ->> mylist  = [1,2,3,4,5]
    ->> mylist = ['1', 1, ages]
    ->> mylist = ['something', 'smells', 'fishy', 'near', 'the', 'wharf']
    We can make a list out of a string (similar to explode in PHP):
    Code:
    ->> mystring = 'something smells fishy near the wharf'
    ->> mystring.split()
    ['something', 'smells', 'fishy', 'near', 'the', 'wharf']
    ->> mystring.split() == mylist
    True
    We can make a new list out of another by filtering it (remember, ages.items() from above...)
    Code:
    ->> ages = {'Marty' : 12, 'June' : 15, 'Harry' : 10}
    ->> can_ride_rollercoaster = [name for (name, age) in ages.items() if age > 10]
    ->> can_ride_rollercoaster
    ['Marty', 'June']
    TUPLES

    Tuples are immutable sequences. Many Python developers use them without realizing it. Consider the following function which returns two bits of data:
    Code:
    def get_port(host):
        return host.ip, host.port
    The return value might look like this: ('10.10.10.1', 8080) ... a tuple.

    Over to you, PHP....
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  3. #3
    Join Date
    Oct 2004
    Location
    LA, CA
    Posts
    1,059
    I think that's misleading...no programming language is really better than another, but the real question is which one is the best for this specific job? Going from PHP to Ruby, I see a lot more power given to me in Ruby but I lose a lot of the control. The files MUST be in select directories and a separate server must be run for the apps. Just my 2 cents.

  4. #4
    This isn't a fight between languages, it's just comparing them (just as the topic title says). First we'll all give an overview of the languages and then provide real-world examples. You might do Ruby overview in the same manner mwatkins did with Python. I'll try to post tomorrow regarding PHP, it's sleep time over here. Great topic mwatkins, I'm looking forward to learning something new.

  5. #5
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    Internet Data Access / sorting example

    Specification: Output only (in this order) symbol, name, and price for the TOP THREE listed stocks using the following URL for data / example shown:

    Code:
    http://finance.yahoo.com/d/quotes.csv?s=IBM,MSFT,YHOO,INTC,CSCO,HPQ,NVDA,AMD&f=nsl1c1v&e=.csv
    "INTL BUSINESS MAC","IBM",92.07,+0.31,4359400                                  
    "MICROSOFT CP","MSFT",29.35,+0.11,47278556                                     
    "YAHOO INC","YHOO",27.40,+0.01,16883332                                        
    "INTEL CP","INTC",21.00,+0.42,45848192                                         
    "CISCO SYS INC","CSCO",26.68,-0.06,49381600                                    
    "HEWLETT PACKARD C","HPQ",40.12,+0.23,13537800                                 
    "NVIDIA CORP","NVDA",36.00,+1.56,14212553                                      
    "ADV MICRO DEVICES","AMD",21.20,+0.13,16914600
    Quick and Dirty:
    Code:
    from urllib2 import urlopen
    import csv
    
    data_source = 'http://finance.yahoo.com/d/quotes.csv?s=IBM,MSFT,YHOO,INTC,CSCO,HPQ,NVDA,AMD&f=nsl1c1v&e=.csv'
    
    data = csv.reader(urlopen('http://finance.yahoo.com/d/quotes.csv?s=IBM,MSFT,YHOO,INTC,CSCO,HPQ,NVDA,AMD&f=nsl1c1v&e=.csv'))
    
    # lets sort it based on the 4th element of the list (base 0, so think "3")
    data = sorted(data, key=lambda x: float(x[3]), reverse=True)
    
    # spit out only the top 3. If the list were empty, nothing would be output
    for name, symbol, last, change, vol in data[:3]:
        print symbol, name, last
    Putting it all together in a more useful and reusable fashion, with some line breaks to make it easier to read:
    Code:
    from urllib2 import urlopen
    import csv
    
    def top_stocks(stocklist, number):
        data = csv.reader(urlopen(data_source % ','.join(stocklist)))
        return sorted(data, 
                              key=lambda x: float(x[3]), 
                              reverse=True)[:number]
    
    # and you'd use it like this...
    
    data_wanted = ['IBM', 'MSFT', 'YHOO', 'INTC', 'CSCO', 'HPQ', 'NVDA', 'AMD']
    for name, symbol, last, change, vol in top_stocks(data_wanted, 3):
        print symbol, name, last
    Returns:
    Code:
    NVDA NVIDIA CORP 36.00
    INTC INTEL CP 21.00
    IBM INTL BUSINESS MAC 92.07

    In this example we do some sorting, reversing; sorting of a complex data type by the proper element. All libraries (urllib2, csv) are part of standard Python.

    I've introduced "lambda" here not because I'm trying to be cute - until fairly recent versions of Python I didn't use lambda all that often. Think of lambda as quick throwaway functions - they can only take a single parameter. In this case using lambda to access the 4th element of each row makes the code shorter than it would have been. I'm not a code-shortness puritan - generally I favour readibility over compressed code any day. But in sort() / sorted() methods and functions lambda has crept into my toolkit.

    Cheers - that's it for me for now.
    Last edited by mwatkins; 11-13-2006 at 10:11 PM.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  6. #6
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    Quote Originally Posted by klarth
    I think that's misleading...no programming language is really better than another, but the real question is which one is the best for this specific job?
    No, no, NO! In this thread we are specifically trying to AVOID the language wars - we are merely comparing languages at the level they deserve to be compared... in detail. We're looking at how each handles different common programming tasks.

    Why? Because an awful lot of folks on WHT keep asking what the differences are, and the tendency is to provide facile answers that don't actually respond to the question. My hope is that this becomes something of a resource.

    And specifically we are avoiding looking at web output, because that opens up having to look at web frameworks. PHP is in a real sense a giant web framework (upon which other frameworks can and have been built as well). With Python and Ruby, you get to pick your poison.

    Quote Originally Posted by klarth
    Going from PHP to Ruby, I see a lot more power given to me in Ruby but I lose a lot of the control. The files MUST be in select directories and a separate server must be run for the apps.
    You are confusing RUBY with RUBY ON RAILS.

    The former is a language; the latter is a web framework that was written in Ruby.

    Rails does indeed require you follow its conventions as to how an application project is set up. That's a choice the framework developer made - impose some constraints so as to make life overall easier for all users, and developers of the framework.

    Discussing web frameworks is an topic big enough to warrant another thread. No doubt we'll do it in time here... but lets not do it now.

    Back to the PHP, Python (and hopefully others... come on you Java and Ruby folks, pitch in!) bake off. Someone else write the next spec. Keep it simple and illustrative.
    Last edited by mwatkins; 11-13-2006 at 10:17 PM.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  7. #7
    Join Date
    Jul 2003
    Location
    Kuwait
    Posts
    5,099
    PHP

    PHP was developed specifically for web development, unlike other languages mentioned here -- which are all general purpose programming languages.

    In creating PHP, its authors borrowed heavily from other well known languages such as Perl and C/C++.

    Basic Types

    Like Python, PHP contains almost all the basic types found in other languages. Unlike Python, however, PHP's types are not objects. Actually, everything in Python is an object, and in PHP, object orientation is more of an afterthought (think back to the initial purpose of the language). However, with PHP5, the OO engine has been brought more inline with what is available in other languages.

    Declarative Differences

    Unlike Python, variable names in PHP must be prefixed with a $ sign, additionally, PHP statements must end in the semicolon ; unless its a part that starts a code block. In Python, there isn't such a requirement (although technically, you can write your Python code with a ; at the end of it, since ; is a continuation character in Python).

    Integers

    PHP Code:
    $i 5;
    $b 34
    Unlike Python, PHP has a increment and decrement operator:

    PHP Code:
    $i 5;
    $i++;
    echo 
    $i//prints 6
    $i--;
    echo $; 
    //prints 5 
    Strings

    PHP makes a distinction between strings encapsulated in since quotes and double quotes. Double quoted strings are parsed for any variables, where single quoted strings are not:

    PHP Code:
    $str 'Hello';
    $i 5;
    $str2 'Hello$i'// prints Hello$i
    $str2 "Hello$i"// prints Hello5 
    PHP supports the following string operators:

    PHP Code:
    $str1 'Hello';
    $str2 'World';
    echo 
    $str1.$str2// concatenation
    echo $str1{2}; // access string via index 
    In addition, the build-in string library provides many string manipulation functions, such as slicing, combining, calculating length, etc.

    Complex Types

    Arrays

    PHP has only one array type, which can be used with associative and numerical indices (unlike Python, there is no formal distinction between the two). Also, in PHP orders of the keys are guaranteed, where as in Python, dictionaries are unordered (meaning you can't step through the keys in a particular order natively -- there are other tools to do it, but its not a feature of the data type).

    PHP Code:

    $a1 
    = array(1,2,3,4);
    $a2 = array('x' => 23'y' => 24,  => 'hello');

    //In addition to the above, there is a special syntax which
    //allows you to create arrays:

    $a3[] = 2;
    $a3[] = 4
    In addition to arrays, there PHP also supports other complex types such as objects and resource types (generally, file handles to pipes in the system).

    Much like strings, arrays have a very large function library to manipulate and contort them (these are all part of the standard PHP library).

    Let see who can come up with the internet access example
    In order to understand recursion, one must first understand recursion.
    If you feel like it, you can read my blog
    Signal > Noise

  8. #8
    RUBY

    According to the home page ruby is:
    A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.
    It has a lot in common with Python in that it is OO from the core but ignores most whitespace like PHP (except newline which it will interpret as ; ). It is a dynamically typed language like both.

    Basic Types

    Unlike PHP there is no $ required when declaring variables unless you want the variable to be global in scope. You can also use @ for instance variables. # is for comments

    Code:
    x=5 #a local var
    $y=6 #a global var
    @z=7 #an instance var
    It does not require ; at the end of a statement but you can use one to add multiple statements to one line.

    Integers

    same as Python. Integers are objects so..

    Code:
    n=-5
    print n.abs()
    ..results in 5. One use of this is with the times method which iterates over a block of code the Integers vaule times. Ruby does not support -- or ++.

    Strings

    also objects. By only beef is that the methods have strange names.

    Code:
    s="hello"
    s.replace("world")
    replaces the string "hello" with "world" like the = operator.

    Code:
    s.sub("world","hello")
    substitutes the string world for hello (I would usually think sub was for substring)
    to get a substring you use brackets. Concatination operator is a +.

    Code:
    s="hello world"[0..5]
    print s+"reader"
    prints hello reader.


    Complex Types

    Arrays

    Ruby has an array object which is similiar to the Python list. You can create an array with a comma dilimited list inside square brackets. The array object has an each method which is similiar to PHPs foreach. It uses a sort of bizzare || notation to reference the value at the current index. so foreach($a as $v) in ruby is a.each{|v|

    Code:
    a=[5,4,3,2,1]
    a.each{|v|
    	v.times{print v}
    	print "\n"
    }
    results in..

    55555
    4444
    333
    22
    1

    Structures

    Ruby also has psudo C style structures


    Code:
    dog = Struct.new("Dog", :name, :age)
    fred = dog.new("fred", 5)
    fred.age=6
    printf "name:%s age:%d", fred.name, fred.age
    prints "name:fred age:6".

    Classes and Objects

    Of course ruby supports classes and objects. This includes inheritence, polymorphism, constructors, destrutors and a special ruby thing called mixins which is an attempt to provide the features of C++ style multiple inheritence without the insanity.

    Code:
    class Sayer
    	def initialize()
    		@mywords=["hello","world"]
    	end
    	
    	def sayit()
    		print(@mywords[0]+" "[email protected][1])
    	end
    end
    
    greeting=Sayer.new()
    greeting.sayit()
    One thing you may notice is ruby's schitzophrenia when it somes to blocks. Typically a block which is iterated over is defined with { ... } while a function or conditional is def (or if) ... end.
    Last edited by nnormal; 11-14-2006 at 01:20 PM.

  9. #9
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    PYTHON ... a little more on strings, and on blocks, inspired by contributions from fyrestrtr and nnormal (thanks!):

    Strings: The following are all valid string literals:
    Code:
    simple = 'A string'
    simple = "A string"
    multiline_is_possible = '''Three single or double
    quotes allow for multi-line
    strings'''
    raw = r'Ignore \n backslashed escape sequences'
    unicode_string = u'This is a unicode-aware "string"'
    Python doesn't suffer from the plague of backslashes that some languages force developers to contend with. When escape characters are an issue (often in complex regular expression handling), the "raw" format r'this is a \narfy raw string' disables escape character substitution.

    Python also supports Unicode in a very complete way. In the next major evolution of Python, all strings will become unicode "strings". (Incidentally the lack of proper Unicode support was, years ago, one of the reasons why I moved away from PHP; its still a weak spot for Ruby too as I understand).

    Python supports the C-style sprintf format parameters - man sprintf. Note the use of a tuple in the second example:
    Code:
    % pythoni
    Python 2.5 (r25:51908, Oct 25 2006, 06:36:09) 
    [GCC 3.4.4 [FreeBSD] 20050518] on freebsd6
    Type "help", "copyright", "credits" or "license" for more information.
    ->> 'Jane is %d years old' % 15
    'Jane is 15 years old'
    ->> "Jane is %d years old and her dog's name is %s" % (15, 'Max')
    "Jane is 15 years old and her dog's name is Max"
    Docstrings: Documenting a function, class, method or module is possible using "docstrings" - an optional, but encouraged - feature - the first unassigned string literal found after definition of same. eg:
    Code:
    def my_function(foo, bar):
        """(foo : Foo, bar : [bar,]) -> [baz,]
        
        Returns a list of Baz objects produced from Bar.
        """
        return [Baz(b) for b in bar if b.has_foo(foo)]
    Since we are discussing docstrings this is an opportune time to show how they are used in the real world. We'll take our first look at Objects in Python while we are here.

    Python comes with a tool called pydoc which you can call from the command line or it'll run a mini-web server that allows you to browse your documentation which is autogenerated from function and class definitions and the docstrings contained within.

    Also as noted, help(someobject) will return the docstring. Docstrings are also accessible from an object: print someobject.__doc__ will return the docstring or None if not present. A docstring doesn't *have* to be a triple quoted string, but most Python developers have adopted the convention - it makes it stand out in the code, and encourages adding to documentation when you feel the urge. Self-documenting code is the goal; there are many add-on documentation generators that provide additional functionality.
    Code:
    class Person:
        """
        A representation of an individual; this version allows
        any data to be modified at any time.
        """
        def __init__(self, first_name, last_name):
            """(first_name : string, last_name : string)
            """
            self.first_name = first_name
            self.last_name = last_name
            self.id = None
    
        def set_id(self, id):
            self.id = id
    
    class Employee(Person):
        """Simple subclass of Person, changes set_id.
        """
        def set_id(self, id):
            """(id : int)
            Raises ValueError if already set.
            """
            if self.id is not None:
                raise ValueError, 'id may not be changed once set'
            self.id = id
    Blocks:

    Now that we have some example code showing off classes and methods, we should also note here that blocks are defined in Python not with braces or statements (like begin|end, if|fi, etc) but with **whitespace**.

    Yes, that's right - indentation actually means something in Python. Because this is unusual for most of us coming from other languages, many people find this objectionable. But I've run into very few people who still think its objectionable once they start using the language. Here's why.

    Many programming languages use characters (){};!. and so on for delimiting where blocks of code begin or end. Some languages use keywords such as "begin" and "end". Almost all languages that use characters or keywords to mark out blocks cause a programmer to think about blocks *twice*.

    Think about it... a developer *must* use the language's block scheme; and most developers *choose* to implement their own blocking identification in the form of indentation, simply for code readability. For example, there's nothing wrong with writing "Hello World" (Java) like this:

    Code:
        class HelloWorldApp {public static void main(String[] args)
        {System.out.println("Hello World!");}}
    But most developers will write it like this, for readability (and argue about where the braces should go, too!):
    Code:
        class HelloWorldApp {
            public static void main(String[] args) {
                System.out.println("Hello World!"); // Display the string.
                }
        }
    Python takes a different approach. What is good for the parser is also good for humans. In Python there is no ambiguity about indentation, ever, and because of this blocking-level errors tend to be both less frequent but also easier to detect.

    Note the Python app is one line long (print 'Hello World!') but for this example I'll duplicate the Java style just to illustrate the lack of braces:
    Code:
        class HelloWorldApp:
            def __init__(self):
                print 'Hello World'
    A colon signals a block start; indentation MUST follow, and the block is done when indentation returns to the previous level. No confusion, and no braces litering the code. Python code tends to have a nice look of uniformity and indeed the language tends to encourage a "one way to do it" mentality which makes for more maintainable code, which is a particularly strong selling point for big projects.

    (ps, if any WHT admins are reading this, is there a code syntax highlighter for this forum for Python?)
    Last edited by mwatkins; 11-14-2006 at 01:56 PM.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  10. #10
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    Anyone want to suggest an example db schema? Something simple with a few relations - like a basic blog, basic wiki or a recipe database -- suggesting the latter in part due to a PHP, Ruby, Python round up another group did not long ago, using an O'Reilly article, I believe, as the basis. I'll dig up that schema.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  11. #11
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    To compare native (not framework) database access by language, I suggest we use the example schema (a simple Recipe collection) in this O'Reilly article: http://www.onlamp.com/pub/a/onlamp/2.../20/rails.html

    SQL itself:
    http://www.onlamp.com/onlamp/2005/03...s/cookbook.sql

    In case that file disappears, the essence:

    Code:
    CREATE TABLE `categories` (
      `id` int(6) unsigned NOT NULL auto_increment,
      `name` varchar(50) default NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
    CREATE TABLE `recipes` (
      `id` int(6) unsigned NOT NULL auto_increment,
      `title` varchar(255) NOT NULL default '',
      `description` varchar(255) default NULL,
      `date` date default NULL,
      `instructions` text,
      `category_id` int(6) default NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
    INSERT INTO `recipes` VALUES (1,'Hot Chips','Only for the brave!','2004-11-11','    Sprinkle hot-pepper sauce on corn chips.\r\n  ',1);
    INSERT INTO `recipes` VALUES (2,'Ice Water','Everyone\'s favorite.','2004-11-11','Put ice cubes in a glass of water.\r\n  ',2);
    The O'Reilly article itself (and Part 2 of same) illustrates using a framework (Ruby on Rails) so we won't have to do that. Also, a group exploring Django (Python) and Symfony (PHP) frameworks as well as Rails has produced versions for both those frameworks.

    Remember, for this illustration we just want to use whatever bare bones DB API the language comes with.

    In Python's case a DB API spec is published and various database adaptors are then written following that spec. There's broad support for MySql, Postgres, Oracle, MS SQL Server, Informix and a host of others - but most are provided outside of Python itself. I'll do the Python demo using the built-in support for sqlite and perhaps also will show the same for a popular open source Postgres adaptor "psycopg".

    I do think it would be useful to show off one object relational mapper per language too, just to contrast raw DB access with easier or easy DB/object manipulation. But raw first.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  12. #12
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    The above schema was for MySQL. FYI here's:

    Postgres:
    Code:
    create table categories (
        id serial, 
        name varchar(50), 
        PRIMARY KEY(id)
    );
    
    create table recipe (
        id serial, 
        name varchar(255) not null, 
        description varchar(255), 
        date date, 
        instructions text, 
        category_id integer,
        PRIMARY KEY(id)
    );
    sqlite:
    Code:
    create table categories (
        id integer  AUTOINCREMENT, 
        name varchar(255),
        PRIMARY KEY(id),
    );
    
    create table recipe (
        id integer AUTOINCREMENT, 
        name varchar(255) not null, 
        description varchar(255), 
        date date, 
        instructions text, 
        category_id integer,
        PRIMARY KEY(id)
    );
    COMMIT;
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  13. #13
    Join Date
    Oct 2006
    Location
    The jungle
    Posts
    48
    I'm going to take the liberty to exposed my inquiries and doubts on this thread even though i'm not a professional programmer.

    I've been following Mwatkins devotion to Python since one of my first threads 'php vs html' and then another thread called 'php vs Asp'.

    As Mwatkins seems to know a lot about python and seems to have lots of experience in this field. He made me focus my attention towards this software some time ago.

    Python looks pretty interesting indeed. But one of the things that have been kept me wondering 'how in the hell do you do that' in python is the integration between python and html and css.

    In PHP, for me is simple: Because PHP and html both use tags, It's kind of easy to mix and join the both of them. For example, let's take a look of how i created an online form for my website (some of the code not all obviuosly):

    <table width="100%" border="0" cellpadding="0" cellspacing="8" class="tabla_contenido">
    <tr>
    <td><img src="../images/titulos/tit_contacto.gif" alt="Formulario de cont&aacute;cto" width="250" height="25" /></td>
    </tr>
    <tr>
    <td><div align="justify" class="margen_contenido">

    (the above are html tags, and below starts the php coding)

    <?php if (isset($error['notsend'])) { ?>
    <h1 class="format_h1">Server error.</h1>
    <p class="warning"><?php echo $error['notsend']; ?></p>
    <?php } elseif ($mailsent) { ?>
    <h1>thank you message </h1>
    <p>in here goes a thank you for your comments message</p>
    <?php } else { ?>
    If you want to contact me, fill the contact form below
    <?php } ?>
    <?php if (!$mailsent) { ?>

    (and below starts the form the user will use to input his/her info)

    <form action="<?php $_SERVER['PHP_SELF']; ?>" method="post" name="formacontacto" id="formacontacto" onsubmit="YY_checkform('formacontacto');return document.MM_returnValue">


    Now, the good thing (and bad thing at the same time i guess) is that you can put PHP anywhere you want between the html tags. It's good because you just start to code between the web site you already have, but It's bad because at the end you'll have your code mixed with the html tags (altough you can use php includes to put the code in another page).

    This kind of approach seems very straightforward to me.

    The process to create a dinamic web app goes like this (in php):

    1. I create the whole static website in plain html and css (in .php extension files)

    2. Once i'm done, I start to make it dinamically by entering pieces of code lines using <?php put your code here ?>

    So at the end, the code on my page will look something like this:

    <html tags>
    <php tags>
    <html tags>
    <php tags>
    <php tags>
    <html tags>

    So, It's kind of straightforward to create a web site like this. Using html and php tags all clustered together.

    What I've been wondering is how do you create web apps using python?.

    Do you first create the entire app on its own, and then when it's finished you somehow put it together with your html code??

    Or is it more like the php-html approach?.

    I've no idea how python and html-css integration works. I understand it in PHP (because its tag nature makes it like html). But with python i don't understand how it goes. I hope somebody would explain me this.

    Going back to the example of the online contact form. How do you create the exact same thing using python?.

    You can put how it will be accomplished in python in general terms as I did here. I'm sorry if this sound stupid and basic to you considering that i'm practically a newbie in this programming stuff arena.

    But i thing it will fit into the subject of this thread, won't it?
    Last edited by Andresito; 11-14-2006 at 10:10 PM.
    E-business Guru wannabe

  14. #14
    Join Date
    Jul 2002
    Posts
    3,352
    i don't think you want to mix in presentation tire(GUI) with business logic.

    for example, namespace in .Net can allow you to reuse code by say

    Test.Framework.Person - which is how i access Person's class and i can inhert that piece of logic to create Employee class and generate a .dll which i can plug in to any future project that require something similar.

    this is why PHP is a training wheel without the bike. when you want to reuse your code, it won't be possible because of PHP's half-baked OOP and the programers that it created.

    i don't know how Python does it but ASP.net have code behind that seperate out Web GUI from Code.

    let's look at RoR, it use desgin pattern MVC http://en.wikipedia.org/wiki/Model-view-controller

    * Model: The domain-specific representation of the information on which the application operates. The model is another name for the domain layer. Domain logic adds meaning to raw data (e.g., calculating if today is the user's birthday, or the totals, taxes and shipping charges for shopping cart items).
    o Many applications use a persistent storage mechanism (such as a database) to store data. MVC does not specifically mention the data access layer because it is understood to be underneath or encapsulated by the Model.
    * View: Renders the model into a form suitable for interaction, typically a user interface element. MVC is often seen in web applications, where the view is the HTML page and the code which gathers dynamic data for the page.
    * Controller: Processes and responds to events, typically user actions, and may invoke changes on the model and view.

    MVC - 3 tires, GUI, Code and Database(storage)
    Last edited by jt2377; 11-15-2006 at 12:04 AM.

  15. #15
    while I wont argue about php's half baked OO, I dont think it is very hard to write modular and reusable code if you know what you are doing. There are MVC frameworks for php and it is not hard to follow that pattern even without using one. There is definitely a bike there (even if it's got a funky banana seat and some of those 70s style streamers coming out the handles). Another thing I would argue is that one mans training wheels is another's tool for rapid development.

  16. #16
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    Andresito - your question is an excellent one and I'd intended that this thread would eventually address, but first we have to dig into some other subjects. I guess this reply will count towards: "How do PHP, Python, Ruby, etc" deal with namespaces.

    I'm not going to go into this fully here quite yet but will in time. But lets address your principle question -- a common question coming from users of PHP and other tag-based web application approaches.

    The short answer is yes, you can adopt a Python-based solution that allows you to mix tags with html, much in the same way as you do now. The slightly longer answer is No, you don't want to go down that route. The even longer answer is Yes and No, you can have the best of both worlds by striving to keep separate objects / logic as much as possible from presentation (using templates).

    PYTHON - Namespaces

    jt2377 has raised the key point - no matter what the language, its simply good practice / design to separate presentation from logic wherever you can. Your code will be much more maintainable; you'll be able to write tests that call your objects and logic. Sadly PHP (nor any language really) doesn't enforce this but in PHP's case it actually encourages the opposite - mixing of objects, presentation, logic, html... everywhere - particularly for new developers with perhaps little formal training.

    The buzzword these days is MVC, which is just a fancy way of saying what we've been saying... keep your objects and your presentation (html, xml, rss, email, gui, whatever) as separate as possible.

    So for my "Person" and "Employee" object examples mentioned in a prior post, if I needed a user interface to list, add, update, and delete "Persons" I would have the UI defined in another module.

    We talk about namespaces a lot - maybe some practical examples will help. While in some level similar to including a PHP file within another (require), more object oriented languages tend to support the concept of * namespaces *, which are much more powerful in that they allow you to modularize your code, and "include" only that which you really need, i.e.
    Code:
    from urllib2 import urlopen
    In that statement I just imported a single function, not the entire module urllib2. Python (and .NET and Ruby) all have the concept of namespaces.

    Maybe laying out a typical project (for me) in Python might help in understanding how namespaces aid in breaking up a project into logical modules, and how that can deliver more reusability.
    Code:
    /recipe
        /bin
        /bin                    - scripts that interact with the system, for example a
                                  database initialization (gets used frequently during dev
                                  and testing, and for a new instance of the application)
    
        /obj                    - application objects
            recipe.py
            category.py
    
        /obj/test               - unit tests. My philosophy is never leave the 
                                  app in a failed state, even during development. I 
                                  frequently write the tests before having finished 
                                  writing the objects themselves. A utility script
                                  runs all the tests or a single test, and by using a 
                                  consistent naming convention I can be editing the 
                                  corresponding module (say recipe.py) and with a
                                  keypress, run the test script from my editor.
    
            utest_recipe.py
            utest_category.py
    
        /ui                     - user interface classes and controllers. Ignore the `qpy`
                                  file extension, for all intents and purposes these are regular
                                  python files.
            recipe.qpy
            category.qpy
    
        slash.qpy               - the "root" controller of the application.
    Oops, pardon me for adding more info than was needed. Anyway the point I was trying to make with this is that for any app I write, large or small, I break the components down in a similar manner. Presentation is always kept separate.

    Since some projects I work on have both web and GUI clients, keeping the core objects completely separate from presentation has obvious benefits in reusability. When I develop an object that has broader usefulness than a single project, it gets moved from /obj in this project to my library package's /obj and I simply import the object from that library's namespace.

    Category in this demonstration application is a good example of that, so where Category is needed in this application, it'll change from:
    Code:
    from recipe.obj.category import Category
    to
    Code:
    from parlez.obj.category import Category
    Or, if the app was very large and I didn't want to update how Category was imported in many modules (unlikely, but this is just an example) I could still move Category out to my library package, and the recipe app's category.py could simply include one line:
    Code:
    from parlez.obj.category import *
    If I did need to import an entire module, but didn't want to pollute the namespace of the module I'm importing to, I do something like this:
    Code:
    import sys
    Which gives me access to all the functionality contained within sys under the namespace 'sys':
    Code:
    sys.path.append('/an/example')

    So, how does a web browser get to view a list of recipes? Edit a recipe? There's no "index.php" (or "index.py") file, so how does that all work? Lets talk about that in a later installment. We really should drift back to basics here for a while, but I hope this discussion of namespaces and separating objects (models) from presentation (views) helps in the future.
    Last edited by mwatkins; 11-15-2006 at 12:53 PM.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  17. #17
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    Quote Originally Posted by nnormal
    while I wont argue about php's half baked OO, I dont think it is very hard to write modular and reusable code if you know what you are doing.
    I agree.
    Quote Originally Posted by nnormal
    There are MVC frameworks for php and it is not hard to follow that pattern even without using one. There is definitely a bike there (even if it's got a funky banana seat and some of those 70s style streamers coming out the handles). Another thing I would argue is that one mans training wheels is another's tool for rapid development.
    I suspect you and I would also agree that the easy facility by which PHP (and ASP too) newbies can embed code in html does tend to lead to a lot of bad practice. One has to write a big app and then maintain it before one is even aware there is a problem.

    Despite all the power in Python (or C# or Java or many other languages) its still perfectly possible to write horrible unmaintainable code. Perhaps its an even bigger problem with these modern dynamic languages (like PHP, Python, Ruby and such but particularly the PHP/ASP genre) because they present little barrier to entry for newcomers... people can just start hacking and before they know it they have a big mess. Its not a specific indictment of a language or its design, just a side effect of the accessibility such languages offer.

    I don't want to see this thread deteriorate into a 'better than this' discussion, so hopefully everyone contributing can keep it at the level of "here's how XYZ does this, and ABC does that". It'll help the newcomers - of which there appear to be an neverending supply at WHT(!) - much more.
    Last edited by mwatkins; 11-15-2006 at 12:55 PM.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  18. #18
    Join Date
    Nov 2004
    Location
    HK
    Posts
    309
    take a look at

    http://modpython.org/live/current/do...pyapi-psp.html
    http://www.cheetahtemplate.org/


    Quote Originally Posted by Andresito
    Going back to the example of the online contact form. How do you create the exact same thing using python?.
    Rails in DA - Ruby on Rails plugin for Directdmin | DA-Tomcat - Tomcat Manager plugin for Directdmin
    DA-PgSQL - PostgreSQL plugin for Directdmin | IP Deny Manager - IP Deny Manager plugin for Directdmin
    DeeperAdmin - Manager your DirectAdmin server "deeper"
    Order now at http://www.daplugin.com

  19. #19
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    Thanks hehachris - I should have put a link to PSP in there. In addition to PSP there are a literal TON of different templating approaches you can use with Python - from Cheetah (an long time player) to Genshi http://genshi.edgewall.org/ (getting very popular) to systems based on HTML::Mason (Myghty) http://www.myghty.org/.

    What's more common than PSP these days is to break up objects and presentation, and employ one of these templating systems for presentation. When you've got web designers as part of the project team, that's a powerful approach.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  20. #20
    Join Date
    Jul 2002
    Posts
    3,352
    Quote Originally Posted by nnormal
    while I wont argue about php's half baked OO, I dont think it is very hard to write modular and reusable code if you know what you are doing. There are MVC frameworks for php and it is not hard to follow that pattern even without using one. There is definitely a bike there (even if it's got a funky banana seat and some of those 70s style streamers coming out the handles). Another thing I would argue is that one mans training wheels is another's tool for rapid development.
    I'm not saying PHP doesn't have MVC frameworks. my point is you don't want to mix php script with html. it's fine if the program is small but it's a nightmare when your app became big and you have to hunt down each logic inside your view.

    i do agree with you that PHP is great for rapid development kinda like VB6. oh that take me back...i love VB6 for RAD.

  21. #21
    Join Date
    Oct 2006
    Location
    The jungle
    Posts
    48
    I do agree with Mwatkins that you should always separate logic from presentation.

    But again, I haven't understand completely how to put togheter your app code with your html code.

    As Mwatkins exposed previously. Now I understand that you must modularized your code into separate pieces that you can reuse in different apps.

    That makes perfect sense. Because It's easy to create, test, maintain and then reuse.

    I wish i just knew how to mix it later with the html code.

    I'm going to tell you my story so you can understand my point a little better. Please bear with me LOL

    My story with programming goes something like this:

    About some time ago i wanted to make an online business selling ebooks. I didn't have any money at the time so I couldn't invest in it. So what did i do then?. I started to do it all by myself.

    I grabed a book on Dreamwaver and learn everything i could. After months of learning and struggle...I finally created a pretty cool static website, but then i realized this site looks pretty but It didn't have any functionality whatsoever.

    So i needed to start learning how to programm web sites. I chose PHP MySQL because there were a lot of contributions out there and I could see how to put it togheter with my html code.

    I didn't choose python or ruby or any other language simply because they weren't much popular as php (at least for web development).

    Now I realize that there are more efficient ways to programm and much powerful languages than php.

    I don't want to learn bad programming practices. I want to learn good programming practices as I'm starting on this.

    As Mwatkins stated before, separating logic from presentation is the way to go. Also modularizing and reusing code.

    But the reason i haven't switch from php to python is because I have no clue how to mix it with my html files (the html files I already have of my pretty cool static web site, remember?).

    So, Mwatkins has explained us a lot about python and good programming practices. I've learned a lot from his posts.

    But again, how do i mixed an app created in python with my html files????.

    In php is pretty simple and straightforward to me: Just add php tags (<?php ?>) anywhere you need it and mix it with forms and databases.

    Mwatkins, you said that you could also do that in python but that It wasn't the way to go. You said that the way to go was by creating your apps separately, in a modular way, and then join them together with the html (presentation) by managing some sort of template or something like this...am i right?...

    Ok, let's assume for a minute that I have created a shopping cart in python. (After several months of struggle.. i finally have my precious app).

    Now, the million dolar question: How do i integrate my new app with my old static and pretty cool website???.

    This has always been the question that has been on my mind. Maybe if i had a clue to how to perform this, maybe i would have given python a try.

    I got really interested in python when Mwatkins said that something that you do in 1000 lines of code in php, you can do it in python in 100 lines of code.

    But i haven't made that transition because i simply don't understand the integration between logic and presentation.

    I'm sorry if i repeated this like a thousand times, but i want to make my point clear LOL.

    I was wondering if Mwatkins can give us an example of how to accomplish this.
    For instance.....i have some challenge for you....

    Can i give you a simple static page with an online contact form so you could make it work in python???.

    I already did that in php. But i want to see how that same thing is accomplished in python and what the differences are...

    If you are up to the challenge I'll send you the static online form for you to start having fun with it...

    I can even post the entire code to do that in php. It would be interesting to see the code for both languages..python and php.

    So if you are up to this challenge, we could start with a single table which contains a simple contact form. All html...and then we could code it in both languages to make it work....

    what do i mean by 'work'?: that a user enter his name, email and a message... and then..when she click on the submitt button, the info is sent to an email address...

    I think you learn more from examples.....and this would be interesting. well let me know if you are interested.

    Another thing: I have a question regarding this post formatting options..

    How do i make the code to be in that white box like you guys do?. I don't know how to do that but I've noticed that you put all code in white boxes???...
    Last edited by Andresito; 11-15-2006 at 05:22 PM.
    E-business Guru wannabe

  22. #22
    I suspect you and I would also agree that the easy facility by which PHP (and ASP too) newbies can embed code in html does tend to lead to a lot of bad practice.
    I might be playing devils advocate a bit here and while I do agree with you - I'm not really sure how much this matters. I started writing code in basic using goto and line numbers and the like. In our current epoch this kind of programming is straight up criminal. That is not what I was learning when I was a total newbie.

    Newbies need to learn stuff that developers of all levels just take for granted. What is a block of code? What is a conditional? How do I save this variable somewhere so my next thingywhatsit knows about it? MVC, design patterns, and even OO in general are not the place to start IMO. Just recognizing that a block of code is better put into a function rather than rewriting it over and over is the kind of thing newbies are still trying to get.

    I think the most important thing to do as a newbie is to get your hands dirty ASAP. Write mangled terrible code. Write the whole program in one procedure if you have to but learn from your mistakes. Rewrite code that you have written so it is more concise and more modular later when you have more understanding. This is how you learn the tricks of the trade. It is when you understand why not to do something that you understand why doing it right in the first place is not just academic or semantics but actually easier on yourself.

    One has to write a big app and then maintain it before one is even aware there is a problem.
    This is absolutely correct and no time reading design patterns or any of the stuff the been-around-the-block developers write on WHT will change that. Although you may look back and say "so thaaaat's what they were on about" (I know it's happened to me).

    oh and formatting code--

    [ code ] <!--- code goes here ---> [ / code ] (without the spaces)

  23. #23
    Internet Data Access / sorting example

    I'll sort the data based on the stock price (I presume it is the stock price). Highest goes first, I'll display top 3.

    PHP Code:
    $handle = @fopen('http://finance.yahoo.com/d/quotes.csv?s=IBM,MSFT,YHOO,INTC,CSCO,HPQ,NVDA,AMD&f=nsl1c1v&e=.csv''r') or die('Unable to open CSV file');

    while ((
    $csv_data fgetcsv($handle1023",")) !== FALSE)
        
    $sorted_array[] = array($csv_data[2], $csv_data[1], $csv_data[0]);    

    rsort($sorted_array);

    foreach(
    $sorted_array as $index => $data)
    {
        echo 
    '<p>'$data[0] .' - '$data[1] .' - '$data[2] .'</p>';
        
        if(
    $i++ == 2) break;    

    We get:

    HTML Code:
    93.11 - IBM - INTL BUSINESS MAC
    
    39.79 - HPQ - HEWLETT PACKARD C
    
    35.76 - NVDA - NVIDIA CORP
    There's definitely more ways to play around with arrays, and probably shorter / more efficient ones.



    Raw database access

    We have the DB schema from the previous page so just a basic raw example to accessing the DB using mysql_ (not mysqli).

    PHP Code:

    @mysql_connect('localhost''root''root') or die('Cannot connect to the MySQL server: 'mysql_error());
    @
    mysql_select_db('some_db') or die('Cannot access the specified database. Error reported by server: 'mysql_error());

    // now some querying, i'll just display recipe categories

    $query = @mysql_query("SELECT id, name FROM `categories` ORDER BY id DESC LIMIT 0, 5") or die('An error occured: 'mysql_error());

    if(
    mysql_num_rows($query))
    {
        while(
    $row mysql_fetch_array($query))
        {
            echo 
    '<p>ID: '$row['id'] .', name: '$row['name'] .'</p>';
        }
    }
    else
    {
        echo 
    '<p>No recipe categories found in the database</p>';


  24. #24
    Join Date
    Oct 2006
    Location
    uk
    Posts
    448
    php owes some of its heritiage to C and shares many of its traits.

    (easy to write insecure code, gives you alot of freedom, gets the job done, poorly implemented Oo, C++ is a mess when you compare it to Java or c#)

    what php python and ruby have in common is they dont enforce strongly typed variables. This is arguablly a stength or weakness.

    strength in its quicker to code without having to worry about datatypes
    weakeness harder to find bugs and causes maintence issues if u dont use a naming convention.

  25. #25
    You can write insecure code in any language. I like when I have freedom to mess something up, rather than to be limited. We could also provide examples of insecure code in mentioned languages. I'd like to see all of the specified in the real, working world

    doc_flabby, can you provide an example of insecure code in PHP? Or anyone else?

  26. #26
    Join Date
    Nov 2005
    Location
    Palma de Mallorca, Spain
    Posts
    259
    Quote Originally Posted by doc_flabby
    php owes some of its heritiage to C and shares many of its traits...
    (easy to write insecure code, gives you alot of freedom, gets the job done, [...])
    Hello, I'm enjoying this thread and want to spare my 2 cents.

    I think Doc_flabby made a good point, althought you write insecure code just if you're too lazy to secure the critical parts.

    I feel really comfortable coding in PHP since I wrote and write C and Perl too, so learning PHP was a huge breeze.

    In my behaviour, coding PHP is just an amazing pleasure impossible to adequately describe. You have just exact or similar core functions that Perl and C, so when you have to code PHP, you're at home and more.

    The same freedom and "I'm in control" feeling, when you enjoy creating your own my_extended_core_function just because you find you need it.

    Regards,

    Juan

  27. #27
    Join Date
    Aug 2002
    Location
    Superior, CO, USA
    Posts
    633
    I'm a bit late to this thread and I think it's a great start but I'd like to suggest a slight change in direction (perhaps a new thread). Start by defining a real web based problem (as that is what most of WHT would be interested in) and publicly implement it in the different environments. For example, maybe a simple feedback page with comments and the ability for an admin to manage those comments. Certainly there could be lots of other ideas too. But pick one and use it for all implementations.

    Basically we could define the business problem clearly (yeah, like that ever happens in real life ) and then show how it would be implemented in the different environments. I'd say that the implementation should use the tools available as that might be closer to a real world implementation.

    Thoughts?
    Need Java help? Want to help people who do? Sit down with a cup of Java at the hotjoe forums.

  28. #28
    stdunbar, that's exactly why this thread exists and what we're trying to do. So far, we've all contributed by defining what data types exist in 3 languages (PHP, Ruby, Python).

    Also, we've shown a simple data manipulation - parsing a CSV file and connecting to database. We can make a feedback form, sure, but no need for a new thread. Excellent idea. I'd like to see that done in bare-bones language, meaning no frameworks whatsoever behind them (no Ruby on Rails or Django or ZF).

    Also, I'd like to see examples for each of the languages from more than one user so we can see in how many ways something can be accomplished. I'll add my contribution later today when I catch some time.

    Is there anyone who's willing to actually post some code and stop all the talking except mwatkins, nnormal and fyrestrtr?

  29. #29
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    stdunbar-- I didn't want to *start* with a web based problem because part of what I hope we all address is how different languages approach the basics, first. Partly to put context around any web applet we might build here, and partly to leave a resource here on WHT that we can direct the almost daily, certainly weekly, questions from budding programmers "which language is best" (never liked the format of that question).

    I'll contribute a raw db example, an "ORM" db example today and then see what's next on the list.

    andresito - just hang tight, we'll get to your question in short order.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  30. #30
    Join Date
    Oct 2006
    Location
    The jungle
    Posts
    48
    Ok, this is how i have created my online contact form in PHP. It has 3 basic fields: Name, email, and message. And it validates each one of them.

    Code:
    <?php 
    //set flag to indicate whether mail has been sent
    $mailsent = false;
    
    if (array_key_exists('sendform',$_POST)) {
    // mail proccesing script
    // remove escape characters from POST array
    if (get_magic_quotes_gpc()) {
      function stripslashes_deep($value) {
        $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
        return $value;
        }
      $_POST = array_map('stripslashes_deep', $_POST);
      }
      
    // validate the input, beggining with name field
    $name = trim($_POST['name']);
    if (empty($name)) {
    	$error['name'] = 'Please, enter your name';
    }
    
    // validating the email field
    $email = $_POST['email'];
    // check for valid email address
    $pattern = '/^[^@]+@[^\s\r\n\'";,@%]+$/';
    if (!preg_match($pattern, trim($email))) {
      $error['email'] = 'Please, enter a valid email address';
      }
      
    // validating the message field 
    $messagebody = trim($_POST['message']);
    if (empty($messagebody)) {
    	$error['message'] = 'Please, enter a message';
    } 
    
    //initialize variables
    $to = [email protected],[email protected]';
    $subject = 'Message for my domain';
    
    //build the message
    $message = "From: $name\n\n";
    $message .= "Email: $email\n\n";
    $message .= "Message: $messagebody";
    
    // build the additional headers
    $additionalheaders = "From: Iwokis<[email protected]>\r\n";
    $additionalheaders .= "Reply to: $email";
    
    //send the email if there are no errors
    	if (!isset($error)) {
    		$mailsent = mail($to,$subject,$message,$additionalheaders);
    		// check that the email was sent sucessfully
    		if (!$mailsent) {
    			$error['notsend'] = 'Sorry. There was a problem sending your message. Please, try later';
    		}
    	}
    }
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    This code goes before the Document declaration type (you can see it at the bottom of the code).

    And this is the code I've put on the body of my web page:

    Code:
    <table width="100%"  border="0" cellpadding="0" cellspacing="8" class="tabla_contenido">
          <tr>
            <td><img src="../images/titulos/tit_contacto.gif" alt="Contact form" width="250" height="25" /></td>
          </tr>
          <tr>
            <td><div align="justify" class="margen_contenido">
              <?php if (isset($error['notsend'])) { ?>
                <h1 class="format_h1">Server error.</h1>
                <p class="warning"><?php echo $error['notsend']; ?></p>
                <?php } elseif ($mailsent) { ?>
                <h1>thank you message </h1>
                <p>in here goes a thank you for your comments message</p>
                <?php } else { ?>
                To get in touch with us, fill out the form below
                <?php } ?>
              <?php if (!$mailsent) { ?>
              <form action="<?php $_SERVER['PHP_SELF']; ?>" method="post" name="formacontacto" id="formacontacto" onsubmit="YY_checkform('formacontacto');return document.MM_returnValue">
                <table width="100%" border="0" align="center" cellpadding="5" cellspacing="5" bgcolor="#FFFFFF">
                  <!--DWLayoutTable-->
                  <tr valign="top">
                    <td colspan="2" class="titulos_bold" ><label for="label">Name:</label>
                        <?php if (isset($error['name'])) { ?>
                          <span class = "warning"><?php echo $error['name']; ?></span>
                          <?php } ?>
                        <br />
                        <input name="name" type="text" id="name" size="50" <?php if (isset($error)) {echo "value= '$name'";} ?> /></td>
                  </tr>
                  <tr valign="top">
                    <td colspan="2" class="titulos_bold" ><label for="label2">Email:</label>
                        <?php if (isset($error['email'])) { ?>
                          <span class = "warning"><?php echo $error['email']; ?></span>
                          <?php } ?>
                        <br />
                        <input name="email" type="text" id="email" size="50" <?php if (isset($error)) {echo "value= '$email'";} ?> /></td>
                  </tr>
                  <tr valign="top">
                    <td colspan="2" class="titulos_bold" ><label for="message">Message:</label>
                        <?php if (isset($error['message'])) { ?>
                          <span class = "warning"><?php echo $error['message']; ?></span>
                          <?php } ?>
                        <br />
                        <textarea name="message" cols="60" rows="10" id="message"><?php if (isset($error)) {echo $messagebody;} ?></textarea></td>
                  </tr>
                  
                  <tr>
                    <td width="23%" valign="top" class="titulos_bold" ><!--DWLayoutEmptyCell-->&nbsp;</td>
                    <td width="77%"><!--DWLayoutEmptyCell-->&nbsp;</td>
                  </tr>
                  <tr>
                    <td><!--DWLayoutEmptyCell-->&nbsp;</td>
                    <td><div align="left">
                        <input name="Reset" type="reset" class="style21" value="Borrar" />
                        <input name="sendform" type="submit" class="style21" id="sendform" value="Enviar" />
                    </div></td>
                  </tr>
                </table>
              </form>
              <?php } ?>
            </div></td>
          </tr>
        </table>
    Noticed how the html code is mixed with the php tags.

    This is how I have created an online feedback form in PHP. Noticed that I have even validated the fields.

    This is why php is straightforward to me. Using it together with html is kind of easy. Altough i do accept the fact that this mix of html and php is kind of messy and makes it very difficult to go over the code.

    I would like to see this in python. And can anyone make it more simpler in php??. Can anyone separate php code from html tags??. I'd love to see this exact online form created in a much simpler transparent way.
    Last edited by Andresito; 11-16-2006 at 03:56 PM.
    E-business Guru wannabe

  31. #31
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    Its probably fair to say that most Python developers these days use an Object Relational Mapper to access their SQL data; the two with the largest user communities behind them are SQLObject (been around for a while) and SQL Alchemy (picking up a lot of project support). I'm going to demonstrate DB access to a sqlite DB using "raw" DB API access, and then Postgres using SQLObject.

    Python - raw DB API Access

    The Python DB API is a standard to which various implementations for DB access have been built. Python itself comes with a sqlite3 DB API interface; for other databases there are ample providers.

    Docs for sqlite3 are here:
    http://docs.python.org/lib/module-sqlite3.html


    Code:
    conn = sqlite3.connect('recipe.db')
    for (id, name) in c.execute('select * from categories'):
        print '%d: %s' % (id, name)
    Returns:
    1: Snack
    2: Drink

    In the above example results are returned as a list of tuples, i.e. [(1, 'Snack'), (2, 'Drink')], which I access in an easier to remember format using for (id, name) in c.execute ....

    Ok, lets use another database now - Postgres - and throw in an ORM. I used SQLObject for this example because its a little simpler, but in preparing this I also had my first look at SQLAlchemy - quite powerful and not all that difficult to work with. I'll certainly give it another look next time I start up a SQL oriented project.

    SQLObject has this handy feature where it can read the schema from many DB's, saving me the need to define the object in Python (except for perhaps a relation). However I could define all the columns as attributes of my Python object, and then call a .createTable() method which would generate the schema and create the table in the database. Very cool.

    SQLObject

    Code:
    from sqlobject import *
    __connection__ = connectionForURI('postgres:[email protected]/recipe')
    
    # define Category first as we'll be joining to it from Recipe
    class Category(SQLObject):
        class sqlmeta:
            fromDatabase = True
            table = 'categories'  #specified as its different than my class name
    
    class Recipe(SQLObject):
        class sqlmeta:
            fromDatabase = True
        category = ForeignKey('Category')
    And that's it. We can use it like this:

    Code:
    for r in Recipe.select():
      print 'Category: %s Recipe %s: %s' % (r.category.name, r.id, r.name)
    Returns:
    Category: Snack Recipe 1: Hot Chips
    Category: Drink Recipe 2: Ice Water

    Pretty cool - didn't have to think about the join; got easy attribute access (r.category.name) to the related Category object.

    I very often use SQLObject to do quick and dirty work on legacy databases (or other client's systems) - in a script or even at the interpreter prompt. A few lines of code and I have a very powerful object oriented interface to the data.
    Last edited by mwatkins; 11-16-2006 at 10:28 PM.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  32. #32
    mw, what about error reporting? What if I did an error while writing SQL? I must admit that this looks great in Py, but where are errors stored in case something went wrong?

  33. #33
    Join Date
    Nov 2004
    Location
    HK
    Posts
    309
    did you read my post on #18?

    I posted 2 example links.

    Quote Originally Posted by Andresito
    I would like to see this in python. And can anyone make it more simpler in php??. Can anyone separate php code from html tags??. I'd love to see this exact online form created in a much simpler transparent way.
    Rails in DA - Ruby on Rails plugin for Directdmin | DA-Tomcat - Tomcat Manager plugin for Directdmin
    DA-PgSQL - PostgreSQL plugin for Directdmin | IP Deny Manager - IP Deny Manager plugin for Directdmin
    DeeperAdmin - Manager your DirectAdmin server "deeper"
    Order now at http://www.daplugin.com

  34. #34
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    Quote Originally Posted by maxymizer
    mw, what about error reporting? What if I did an error while writing SQL? I must admit that this looks great in Py, but where are errors stored in case something went wrong?
    Python has always had the concept of Exceptions, and like everything else in Python, Exceptions are objects which can be subclassed. I'll talk about Exceptions and try/finally/except in more detail in a bit.

    Lets first look at a simple example of an exception being raised due to a programming flaw. I've intentionally misspelled the table name in the SQL. Assuming the code below is part of a module called "test.py":
    Code:
    c = sqlite3.connect('recipe.db')
    for (id, name) in c.execute('select * from categores'):
        print '%d: %s' % (id, name)
    When we run it:
    Code:
    python test.py
    Traceback (most recent call last):
      File "test.py", line 4, in <module>
        for (id, name) in c.execute('select * from categores'):
    sqlite3.OperationalError: no such table: categores
    So first off, we have a robust exception system that tells us where the error is, and good packages, modules, functions and classes will also tell us the nature of the error - not just that an "Exception" was raised but what sort of Exception. This helps during development and testing to weed out most code faults.

    When you need to protect your application from runtime errors, particularly based on user input, there are two things we need to consider.

    As everyone no doubt knows, one of our big challenges is to protect our system from SQL injection attack. For newcomers to web / application development - SQL injection attacks are when malicious users provide data to your application (as in web form fields) specifically to cause harm - for instance, appending a DROP DATABASE command to a name field. Poorly constructed applications won't properly deal with user input and may well allow such dangerous SQL to pass through to the database.

    Second is protecting the application from legitimate user errors. I'm going to now talk about SQL injection and the automatic quoting features of the Python DB API because this is really important and I forgot to in my DB installment, and in a second post I'll come back to Exception handling.

    Python DB API implementations provide a parameter substitution mechanism that has built in protection. Some modules implement this slightly differently, but these are well known: there are a limited choice of substitution methods which a DB API compliant module must follow.

    Lets fix that query and also add a parameter in a WHERE clause. This example is sqlite3 using the parameter substitution method "?". Note that quoting is automatically looked after -- you, the programmer, rarely need to think about it:
    Code:
    c = sqlite3.connect('recipe.db')
    user_input = "Snack"
    for (id, name) in c.execute('select * from categories WHERE name=?', user_input):
        print '%d: %s' % (id, name)
    Here's an example for Postgres using the psycopg adapter. It uses a parameter substitution method which is already familiar to Python programmers, the named pattern.

    Again, note that all quoting (when needed) is looked after.
    Code:
    cur.execute('select * from categories where id = %(id)s or name = %(name)s', {\
    'id':1, 'name':'Drink'})
    result = cur.dictfetchall()
    for row in result:
        print row
    Returns:
    Code:
    {'id': 1, 'name': 'Snack'}
    {'id': 2, 'name': 'Drink'}
    Now lets satisfy ourselves that these queries are SQL-injection proof by trying an attack:

    Code:
    cur.execute('select * from categories where id = %(id)s or name = %(name)s', {\
    'id':1, 'name':'Drink; drop table categories;'})
    result = cur.dictfetchall()
    for row in result:
        print row
    Returns:
    Code:
    {'id': 1, 'name': 'Snack'}
    And a check of the DB shows that obviously the table was not affected:
    Code:
    recipe=# select * from categories ;
     id | name  
    ----+-------
      1 | Snack
      2 | Drink
    (2 rows)
    Python DB API implementations not only look after quoting in such parameter substitution schemes, but also look after automatic escaping where its needed - i.e. a parameter supplied as string with quotation characters within it would be properly escaped when submitted to the DB as a query.

    Automatic quoting - no backslash plague - is a very good thing.

    Finally - the ORM's like SQLObject and SQL Alchemy also look after all this for you; an added plus of such systems is that since they do a lot of introspection at application start up time, you'll immediately catch stupid errors like my typo example above.

    Also since you tend to build those ORM objects only once, and refer to them frequently, you've got one chunk of code to refer to when needing to make changes. Sure you can do that with nicely modularized code in PHP or Python without the use of an ORM, but its an added benefit that you don't need to think about much to get.

    Ok, next up I'll talk a little more about exception handling. Its both powerful and simple. Maybe someone could take the SQL injection theme and add a bit of detail as to how to protect against that in PHP.

    (and where are our ruby and java friends... come out to play!)
    Last edited by mwatkins; 11-17-2006 at 01:47 PM.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  35. #35
    RUBY

    So I see you guys have moved onto data access and generating web content... You can't really go here in ruby without talking about rails. Of course you can access data using using the ruby-mysql library like this. I'm no going to write out a detailed description of how this works because honestly I don't use it.

    Instead I let rails do the work. Assuming I am in the parent directory to my application I would use

    Code:
    >rails cookbook
    >cd cookbook
    >ruby script/generate model Recipe
    >ruby script/generate controller Recipe
    >ruby script/generate model Category
    >ruby script/generate controller Category
    >ruby script/server

    Then adding a few lines of code to the controller classes:

    Code:
    class RecipeController < ApplicationController
    	scaffold :recipe
    end
    Code:
    class CategoryController < ApplicationController
    	scaffold :category
    end
    and tying them together with
    belongs_to: category #in the recipe model
    and
    has_many: recipe #in the category model

    seeing as this whole db structure is based on a ruby example this makes it very easy to show the result..

    http://www.onlamp.com/onlamp/2005/01.../category4.gif

    is this cheating? yes and no. again one mans cheat may be another's tool for RAD.

  36. #36
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    I've been trying to avoid talking about generating web content as long as possible in this, but at some point its unavoidable.

    Since we are trying to understand some of the *language* differences primarily, we've been attempting to avoid muddying the picture with a big discussion of *frameworks*. That discussion is truly worthy of an entire thread itself, but short examples (like why SQLObect or Rail's scaffold and models) certainly do give people a good reason to dig deeper.

    My hope is that we can keep tying the lower level language features to the practical "but here's how we really do it" stuff.

    When it comes to web output, what I plan on doing is demonstrating some simple CGI based web output and forms manipulation - not because I do much CGI but because I think its important that people know this stuff - not everyone will adopt a big and all encompassing web framework like Rails (Ruby) or Django (Python) - and even if they do, understanding a little about how the web framework actually does its thing would not be a bad thing at all.

    So as soon as I write a bit on exception handling, I'll put out an example - CGI first - of web content generation; web forms. Then I'll show an example using a framework in Python. I picked that Recipe application example from O'Reilly intentionally so we could compare notes with the Ruby folks through it, in case no one ventured to contribute here.
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

  37. #37
    Join Date
    Oct 2006
    Location
    The jungle
    Posts
    48
    Sorry, I didn't have time to check your URLs hehachris. I checked them briefly and I noticed that it's kind of the same thing as PHP, except that instead of using <?php ?> tags, they use "<%@" and "%>".

    But for what i saw, the dinamic is kind the same. Mixing html with <%@" and "%> tags. Correct me If i'm wrong. I'm gonna check those sites more closely as i have any time.

    And yes, It would be interesting to see how to protect the applications from SQL injection attacks in PHP. I hope somebody tell us how.

    Mwatkins, where do you recommend to start learning about python (and developing web applications with python) for the very begginer?. Is it better to start here at http://www.python.org/ or is better to start with a book?.

    Can you recommend us a very good book (or books) in python web development suited for complete beginners?. something that covers the basics and guide us step by step through the whole process of creating web apps in python?.

    An another thing. Leaving aside the fact that php is more popular than python for web development. Based on your experience, do you think that python is easier to learn and work with than php?. Is it more siuted for a beginner or is a program more suited for experienced programmers?.

    If you have to recruit your own team of web developers starting from scratch. Do you encourage them to start learning python inmediately, or do you make them learn first php and then in some point make them swith to python as they have gained more experienced and knowledge?
    Last edited by Andresito; 11-17-2006 at 03:57 PM.
    E-business Guru wannabe

  38. #38
    One note before giving away further examples - if you want to prevent SQL injection attacks, make sure you learn SQL first and then clean any user given input. It's really not that hard to take care of dirty laundry yourself

  39. #39
    The easy way with PHP to clean inputs:

    2 ways:

    PHP5/MySQLi
    PHP Code:
    <?php

    $db 
    = new mysqli("host""my_user""my_password""my_db");
    if (
    mysqli_connect_errno())
    {
      echo 
    'MySQLi Error!: ' mysqli_connect_error();
    }
    else
    {
      if(
    $query $db->prepare("SELECT user FROM users WHERE email = ?"))
      {
        
    $query->bind_param("s"$_POST['email']);
        
        
    $query->execute();

        
    $user $query->fetch_array();

        echo 
    'User is : ' $user['user'];
      }
      else
      {
        echo 
    'Mysqli error! : ' $db->error;
      }
    }
    </span></span>


    PHP4/MySQL (classic way)

    PHP Code:
    <?php

    if($conn mysql_connect("host""my_user""my_password"))
    {
      
    mysql_select_db("my_db"$conn);
      
      
    $query mysql_query("SELECT user FROM user WHERE email = " mysql_real_escape_string($_POST['email'], $conn);
      
      if(!
    $query || mysql_error() !== '')
      {
        echo 
    'Mysql error! : ' mysql_error();
      }
      else
      {
        
    $user mysql_fetch_array($query);
        
        echo 
    'User is : ' $user['user'];
      }
    }
    else
    {
      echo 
    'MySQL connection error!';
    }
    * note, this is a very simplified version

  40. #40
    Join Date
    Nov 2001
    Location
    Vancouver
    Posts
    2,416
    Quote Originally Posted by Andresito
    Based on your experience, do you think that python is easier to learn and work with than php?
    For thos reading this entire thread, I don't think you will be too surprised to see me answer this with a qualified "yes". Some of this is opinion of course, but hopefully fairly put:

    Yes, Python is easier to learn as a language. Why? In as few words as possible:
    - its small. The core of the language is very small. Small means you can remember it.
    - it has data types which make it easier to do certain things (not just "arrays" - python Dicts - but also lists, tuples)
    - its compact, from a character count perspective (fewer characters, fewer lines of code) without being so terse as to be obscure.
    - insistence on indentation to mark code blocks leads to easier to read code, and also forces the newcomer into thinking a certain way
    - its object oriented at its core, and its easy to grasp the basics of its OO and start to use it.
    - opinion: library construction is, in general, better thought out, and it is modular.

    There are real advantages to having a real OO language; oftentimes you can do more with less code. Less code == time writing == less testing == more done in the same amount of time.

    But No, Python is not easier than PHP to *immediately* do program-driven web content generation. Essentially PHP is a web application framework. Once enabled in Apache or lighttpd or the like, you've got PHP available to you either in little bits dribbled throughout html pages, or in a much bigger way.

    So PHP beats Python (and Ruby and Lisp and Scheme and Smalltalk and...) merely because its ubiquitous and built into 99% of the *nix based web servers available for cheap web hosting out there.

    The goal of this discussion is to show why that easy availability and accessibility might not always be the right choice for some developers (or projects) but to be perfectly fair, to demonstrate to some aspiring programmers why they might want to pick PHP. Frankly I think there are some who will grasp PHP easier, and never find they feel limited by PHP. For them PHP might indeed be a much better choice.

    Hopefully by the time we are done this long set of discussions, people will be able to get a good sense of the flavour of all these languages, and also how they compare for doing web development.

    (Trust me we are getting there soon!)
    “Even those who arrange and design shrubberies are under
    considerable economic stress at this period in history.”

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •