Jump to content

Highest Reputation Content

#8885 One Mod Rewrite Rule Won'T Work

Posted by HartleySan on 28 July 2012 - 10:59 AM

If "hiv" is never followed by an e, you could change the one regex as follows:
  • 4

#6644 Just Started This Book Today!

Posted by rob on 26 March 2012 - 10:53 AM

It does affect something it affects the source code layout, which is the whole point of using it, to make source code more readable.
  • 4

#3208 Some Tips When It Comes To Mysql Queries

Posted by Antonio Conte on 20 August 2011 - 11:19 PM

1. Always name your tables the same way:
There are best practice rules for naming tables. They should always be lowercase, split by underscore ( _ ) and named in plural. If you need to build tables for several purposes, (forums, shops, fruits) prefix them so the appear next to each other.


2. Use normalization rules(!!!) when creating a structure for tables
Larry explains the different forms of normalization very good in this book. Read it thoroughly, UNDERSTAND it, and plan your tables well. The rules are really not that hard to understand, and will allow you to cross-reference tables in an easy way later on. It will make you understand how the data you are using are working. It will make your systems a lot easier to build on and to introduce new features. I promise you, THIS is how you become a wizard when it comes to working with data in several tables.

3. Use white space(!) and use UPPERCASE for mysql functions (See tip #4!)
When your queries becomes increasingly more complex, you should really follow these tips. To demonstrate, I will give you two versions of the exact same code:

CREATE VIEW view_goals_per_game AS

SELECT league.season AS season,
league.id AS league_id,
league.name AS league_name,
goals.match_id AS match_id,
clubs1.name AS hometeam,
clubs2.name AS awayteam,
players.id AS player_id,
CONCAT( players.fornavn, ' ', players.etternavn ) AS player_name,
goals.goal_time AS goal_time,
games.kickoff_time AS kickoff_time

FROM abc_players_goals AS goals

INNER JOIN cnk_soccer_games AS games ON ( goals.match_id = games.id )
INNER JOIN cnk_soccer_clubs AS clubs1 ON ( games.club1_id = clubs1.id )
INNER JOIN cnk_soccer_clubs AS clubs2 ON ( games.club2_id = clubs2.id )
INNER JOIN abc_players AS players ON ( goals.player_id = players.id )
INNER JOIN cnk_soccer_league AS league ON ( league.id = games.league_id )

LIMIT 0, 1000

create view view_goals_per_game as select league.season as season, league.id as league_id, league.name as league_name, goals.match_id as match_id, clubs1.name as hometeam, clubs2.name as awayteam, players.id as player_id, concat( players.fornavn, ' ', players.etternavn ) as player_name, goals.goal_time, games.kickoff_time from abc_players_goals as goals inner join cnk_soccer_games as games on ( goals.match_id = games.id ) inner join cnk_soccer_clubs as clubs1 on ( games.club1_id = clubs1.id ) inner join cnk_soccer_clubs as clubs2 on ( games.club2_id = clubs2.id ) inner join abc_players as players on ( goals.player_id = players.id ) inner join cnk_soccer_league as league on ( league.id = games.league_id ) limit 0 , 1000

Whick one would you like to maintain? :blink:

4: Save your queries in a text editor

Yes! It sound idiotic, right? It's not. Think of this happening: You accidentally delete, modify or overwrite a query you've used a lot of time on. It will save you a lot of time, tears and the life of a few keyboards! This is also leading up tip number 5.

5. Use views instead of customizing your dataset in PHP(!)
This is a real life-saver. Think of it as including ONE central PHP file instead on chancing 10 documents every time you make a change. The views should be written to display AS MUCH information as possible. Try to think of every scenario you may want to use the data. Views are, with a few exceptions, for displaying data; hence it's name.

NOTE: After the creation of a view, you CANNOT modify it. This is why you should follow step 4.

- Views are really easy to create:
[u][i]CREATE VIEW the_name_of_the_view AS[/i][/u]
FROM table1

The query used in tip #3 is a view. It would allow you to sort by a specific league, match_id, player_id or by kickoff_time. The view is used to display statistic about the goal scorer in a football match. (soccer for americans) The table for saving goal statistic has three rows(!). Match_id, player_id and goal_time. This is good data normalization, and minimizes redundancy and make for consistent data. That means the table players_goals need to be linked with other tables that holds data about the specific match and the specific player. This is the reason for create a view.

Don't see the point of this?
There really is one - I promise! By writing a view that is general and display a lot of data, I can write SIMPLE queries to get different results:

1. Last five goal scorers with name of both teams, player name and goal time
SELECT hometeam, awayteam, player_name, goal_time
FROM view_goals_per_game 
ORDER BY kickoff_time DESC

2. Display players with most goals in descending order
SELECT player_name, COUNT(*) as goals
FROM view_goals_per_game
GROUP BY player_id

3. Display all goals by a specific player
 SELECT hometeam, awayteam, player_name, goal_time
FROM view_goals_per_game
WHERE player_id = 10
ORDER BY kickoff_time DESC

4. Find all goals in a specific match
SELECT hometeam, awayteam, player_name, goal_time
FROM view_goals_per_game
WHERE match_id = 837

Does it start to make some sense? Instead of repeating and modifying the same hard-to-grasp code over and over again (see tip #3), use a view to make your life simpler. :)

Hope this has helped someone. I have been thinking about writing a lot of different tips when it comes to MySQL. I've been thinking about writing a guide to joins for example. I really don't know if this interests someone or not.

Hoping others will also share tips and experiences when it comes to MySQL. :)
  • 4

#14402 Really Disturbing

Posted by margaux on 1 May 2013 - 4:56 PM

Hey xto, I'm going to try to say this in the nicest way possible -  You're in danger of trying people's patience not because you ask questions, we like questions, but because you ask questions in a way that doesn't provide the information needed to try to answer them.


1. please read the forum guidelines - Look for the little grey text bottom right of most pages, labelled Guidelines

2. please post only RELEVANT code and error messages within code tags. We don't need to see the entire output from your error message. It's actually distracting. Use code tags which are on the edit bar and they look like <>

3. post the relevant CODE, you keep posting the error message but not any code.

4. You should start a new thread for each new question. One reason for doing so is that other people with the same question can search and find your thread. If your question is part of another thread, it won't be found and won't help others.

5. You're asking questions that you should be able to solve 1 because the level of  experience for this book expects you know some basic debugging strategies and 2. with a little bit of online searching you would get some pointers as to where to look for the cause of your error.


I really shouldn't answer your question given the above but ...


somewhere in your code you are referencing an array value using 'sale_price' as the index, which doesn't exist. I'm going to hazard a guess that you have a line that includes $row['sale_price']. From the error dump you posted, you will see there is no index 'sale_price' but there is one named 'price'. Given what info you've provided that's all I can help with. If this doesn't help solve the problem, start a new thread and post the code that is causing the error :)

  • 4

#3399 How Much To Charge A Client For A Website?

Posted by chop on 31 August 2011 - 1:23 PM

Once you really understand what the client wants, you can come up with an estimate as to the total number of hours it will take you to complete. Don't make the mistake of getting into a job in which you don't have a complete understanding as to its scope. Otherwise your hours estimate will be way off and you'll be faced with charging the client much more than the estimate or feeling like you were underpaid. So....

WRITE a document that explains exactly what you're going to do based on what the client has expressed they want verbally. Keep in mind that often even the client doesn't know exactly what he wants. So feel free to add in your own suggestions as you do a little market research of other similar sites. GIVE the document to the client. TALK to the client about all the aspects of it. REVISE it as you discuss it until you both have a solid, clear understanding of it. This will prevent other "things" from being thrown into the mix because the client thought they were included from the start.

Big jobs often involve a lot of research of what is needed before anything can begin. IT IS OKAY to bill your client for this time but it should be done on an hourly bases and the bill should be separate from the bill for the website.

The written document that you share with your client might be called a contract, a specification, or a proposal but it should be absolutely clear to both parties before you drive the first nail (including the time line). The exactness of it will make it easy for you to estimate your hours which can be multiplied by what you feel you need to make without you or the client feeling cheated. Make sure that you include any expenses you might incur such as purchase of images etc..This is most important. If the client likes this document then you send a bill for your time, you get paid, and everyone's happy.

I would ask for a retainer of 50% due fairly early in the project in case you do lots of work and the client bails.

How closely you follow this procedure depends on how big the project is. I have had people I know come to me wanting a simple one page site, plain vanilla, and know exactly what they want on it. They just want something for a web presence. I might say, okay, that will cost you $x so please send a check and it will be up in 2 days. Less time involved, less risk, less money so less need for paperwork.

Think also about where you will host it and if you want to charge the client for annual hosting with a little added on for your occasional support. You can get a discount as a reseller on a host, say $50 and charge the client $99/year.

good luck,
  • 3

#20055 I'm Having Trouble With Sorting Query Results In Chapter 5... Plz Help!

Posted by Emilie on 30 July 2014 - 1:07 PM



What is "wrong", according to you?


The registration date is the same for all users because you entered all of them at one go into the database, and therefore the timestamp corresponding to NOW() is the same for everyone. Because of that, ordering the results by registration_date DESC has no real meaning.


I hope this helps,



  • 3

#15289 Use Data Type Enum For Form Drop-Down Options

Posted by margaux on 2 July 2013 - 5:02 PM

Glad I could provide a little help. When I'm struggling with some code, I use var_dump and print_r to see what is being returned. Then I know how to manipulate the data.

  • 3

#13394 Pls Help Need Urgent Help. The .Inc Extension. Chapter 11

Posted by margaux on 11 March 2013 - 4:45 AM

It's difficult to debug when the code is presented in this way. Please would you use code tags.


At first look, no error immediately jumps out. Which line is line 46? Look at that line and the few lines before it.


Probably not causing this error but it looks like you may have a typo on the tablename in the SELECT statement - users instead of usera?

  • 3

#13112 Forms In Javascript Or Php?

Posted by HartleySan on 19 February 2013 - 10:38 AM

Awesomo, to give you a concrete example, I'm going to use Jonathon's example above because I think it's a good example.
First off, you'll want to attach a JS event handler to the form so that when the form is submitted, JS intercepts the form submission and allows you to do whatever you need to before the form is actually submitted.
This can be accomplished as follows:
document.forms[0].onsubmit = function () {
  return false;
On any HTML page that contains at least one form, JS provides you with the forms array, which is a property of the document object. forms[0] always applies to the first form on the page. You can adjust the array index as need be.
The return false statement actually stops the form from being submitted. (Don't worry though, as we'll actually force the form to be submitted in a second, assuming everything is okay.)
Next, let's imagine that we have a user name text input that must be only letters and numbers, as Jonathon said. Here's a simple JS regex we can write to test for that:
document.forms[0].onsubmit = function () {
  if (/^[A-Za-z0-9]+$/.test(this.elements[0].value)) {
  return false;
The above if statement tests that the user name text input contains only letters (either uppercase or lowercase) and numbers (and is not an empty string). I should note that I make several assumptions with this code:
The user name text input is the first input in the form. This can be seen by the this.elements[0] in the if statement. In this case, this refers to the form object we're interested in, and elements is an array attached to all JS form objects that allows you to access all the inputs items in the form. Naturally, elements[0] refers to the first element in the form. If you'd rather check the user name text input by ID (assuming the ID is "username"), you can replace this.elements[0] with document.getElementById('username'). The value property at the end will give you the actual string entered into the text input object.
If the above if statement evaluates to true, then we can assume that the user name does in fact only contain letters and numbers. That being the case, we should then submit the form normally.
However, if the if statement returns false, then we should change the border of the user name text input to red.
The following code will do just that:
document.forms[0].onsubmit = function () {
  if (/^[A-Za-z0-9]+$/.test(this.elements[0].value)) {
  } else {
    this.elements[0].style.border = '#F00 solid 2px';
  return false;
As before, this refers to the form object in question. this.submit() will actually submit the form as if JS never intercepted the form submit request in the first place.
If the if statement fails, then we use this.elements[0] (or document.getElementById('username'), if you want) to reference the user name text input object, and then change the border to a 2-pixel red border.
That's the basic concept to simple JS form validation built on top of standard PHP form validation.
One of the keys to this method is that you only submit the form when everything is okay.
And naturally, the concepts above can be rinsed and repeated as many times as necessary to validate all your form input.
I hope that helps.

  • 3

#11886 Chapter 1, Sorting Multidimensional Arrays, Pg. 6 Function

Posted by Antonio Conte on 24 December 2012 - 11:55 PM

It compares all values in the array, but that happens internally. This is a pattern called a compator, and is used to compare collections structures like this PHP array (The array structure implements an Interface that makes it Comparable for a Comparator). To use more known examples, the reason why you can use a while loop on a MySQL(i) result object, is that this structure is built on a pattern called an iterator. This is also why arrays support foreach statements. (You can build this into your own classes)

This pattern is often tied to lists of objects in other languages. Let's say you have a Person class. A PersonList would be a class that handles a list of Person objects (Using an array internally). This class can have methods for looping, adding, removing, sorting and a lot of other things. Such classes are called a Collection in other languages, and is a definition for lists, (that's normal arrays in most languages) linkedLists, stacks, queques and other fun data structures, including Hash maps (associative array keys are implemented as a Hash map). In PHP, all of these data structures are defined as ARRAY........ Let that sink in.

The point here is that arrays in PHP is not arrays as you find them in other languages. That is not all bad, and also some of the reason why PHP is so awesome at times. The problem is that it makes it very hard to understand a lot of concepts for PHP developers as they don't understand the data structures strengths and weaknesses. Because we "have it all", very few developers has to think about how sorting, iterating and CRUD operations actually work.

The reason why your examples work is because of this. The standard, built in internal way of ordering arrays is by a method most often call compareTo() in other languages. This method could be implemented in the Person example class of ours through an interface often called Comparable. When that is done, the PersonList can easily compare each Person found in the list and thus sort the array of Person objects. What you basicly do here is to say that PHP's Array structure (A PersonList) should compare all keys called name found in an element (A Person), using either the standard compareTo function defined in the Element or a function you define yourself. (And that function then takes the job of the compareTo function instead)

This is both pretty advanced and pretty simple stuff at the same time. You cannot really understand all this at once, but that is approximaly how it should work. I cannot fully gurantee that's how PHP has actually implemented it, but these are well known patterns in object oriented programming. It can be defined as theory as much as implemented in practice. Once recommendation is to read about data structures if your interested, but if not then just take my word for it. Don't try to understand your toaster, just learn how to use it. ;)

Edit: Sorry about the poor English here, might clean it up a bit tomorrow. Been a great christmas with family, good food and a local liquor called "Akevit". (Aqua vita - water of life) It's a scandinavic speciality liquor that's great with fat food. Try it if you ever visit Denmark, Sweden or Norway. We take great pride in it, but mostly drink it around chirstmas time.
  • 3

#11574 Please Explain Routing Rules Precisely !

Posted by HartleySan on 8 December 2012 - 12:11 PM

Ziggi, sometimes when we try to help people on this forum, we don't get it right the first time.
Quite often, the reason someone is asking a question and the reason they don't understand something is not very clear to us. We don't intentionally try to not answer someone's question.
Antonio and Edward were both doing the best they could to help you. The fact that they (unintentionally) missed the mark and didn't give you the answer you wanted right away is no reason to act the way you did.

A more civil approach would have been to reanalyze your original post(s), think about why Antonio and Edward perhaps weren't able to answer your question, and then politely reprhase your question to hopefully reach a reasonable solution eventually. I guarantee that if you had been polite about it, both Antonio and Edward would have been more than happy to continue helping you until you got the answer you were looking for.

It seems like you're not a native English speaker, so perhaps the source of the arguments was all just a simple misunderstanding on both sides, but at this point, you really have no hope of ever getting any more relevant information to your question. And more than likely, you've ruined any chances you have of ever getting any help on this forum again. Both Antonio and Edward are the two most active and knowledgeable posters on the Yii forum here, so you're probably SOL.

I think you have one of two choices:

1) Apologize for your previous posts, and with time, I think tempers will cool down and we can get back to having civil discussions and everyone can get answers to questions and be happy. Please note that I am not asking you to beg on your knees, but at this point, I think a sincere apology would be nice.

2) Don't post on this forum anymore and consider this a lesson learned for future interactions on forums.

The choice is yours. I also had to swallow my pride recently and apologize for stepping over the line on this forum, and even though it didn't feel good at the time, I'm glad I did apologize and everyone was able to go back to being civil and helping out again. I'd recommend the same for you.
  • 3

#11171 Php Code Allow Smartphone Applications (Iphone, Android) To Connect To My Web...

Posted by HartleySan on 18 November 2012 - 9:39 PM

If you want users to access your site from a web browser on their smartphone, then there is no additional code you need to write. The code would be the same for the desktop version and the smartphone version.
The only likely thing you'd want to change is making the smartphone version easier to view (than the desktop version) on a smartphone.

If, instead, you want to write a native app for iPhone and Android devices, then I suggest you by a book about how to write iPhone and Android apps (which use two separate languages), because PHP is not going to help you there.
  • 3

#11126 Activation

Posted by swisse on 16 November 2012 - 6:25 AM

Hi uncfelt1147,

I'm no expert in PHP, just like you I'm a newbie. I find your query statement a little bit long with all those \n's.
This is the code from Larry's book:

$q = "UPDATE users SET active=NULL WHERE (email='" . mysqli_real_escape_string($dbc, $_GET['x']) . "' AND active='" .mysqli_real_escape_string($dbc, $_GET['y']) . "') LIMIT 1";

I check always with phpMyAdmin that the person I'm activating is recorded in my database.
  • 3

#10822 Access All Objects Of A Class

Posted by Edward on 31 October 2012 - 7:11 AM

Yes you can do this by creating a static array, then you can assign each new instance of the newly created class to that array. This method is often used when storing active database connections.
  • 3

#10152 Pass A Multi Dimensional Array To Hidden Forms

Posted by HartleySan on 24 September 2012 - 6:26 AM

If you really want to, you can do something like the following:

<!DOCTYPE html>

<html lang="en">


    <meta charset="UTF-8">





      if (isset($_POST['submit'])) {

        echo '<pre>';


        echo '</pre>';



    <form action="" method="post">

      <input type="hidden" name="data[]" value="0">

      <input type="hidden" name="data[0][]" value="Cheese">

      <input type="hidden" name="data[0][]" value="Bacon">

      <input type="hidden" name="data[]" value="1">

      <input type="hidden" name="data[1][]" value="Peppers">

      <input type="hidden" name="data[1][]" value="Fork">

      <input type="submit" name="submit" value="Submit">




However, I'm having trouble coming up with a reason you'd want to do that. As rob said, storing that data in a session would probably be better.
  • 3

#13111 Losing $_Get Values After Pressing Reload Button

Posted by HartleySan on 19 February 2013 - 9:54 AM

Hello, Roy. Welcome to the forums. I hope you find them helpful.

I think you have a few options:


1) Store the $ordernbr value in a hidden input in the form on the second page, and then grab that value from the $_POST superglobal when you post the form with the "Reload" button.


2) Save the $ordernbr into a cookie or session.


3) Use JavaScript and Ajax to change part of the form dynamically without actually reloading the page. (This is rather advanced and not really recommended. I more am just presenting it here because it is a possibility.)


Of the three options, I probably wouldn't attempt #3 unless you want a serious challenge.

#2 is a very viable option, but I'm not sure if Larry talks about cookies/sessions in the book, so I'd check that first.

So that leaves us with option #1.


Basically, when you are using PHP to write the HTML for the form on the second page, add am extra hidden input element (I think Larry talks about these in the book) with a value equal to the $ordernbr variable. That way, when you post the second form by clicking the "Reload" button, that $ordernbr value will be posted and accessible in the $_POST superglobal under the name set for the hidden input.

Does that make sense?

  • 3