Jump to content
Larry Ullman's Book Forums

ericp

Members
  • Posts

    58
  • Joined

  • Last visited

Posts posted by ericp

  1. Perhaps, my English is not sufficient enough to explain the file system that I organized, or I chose the wrong word to explain it.

     

    Yes, you are right, and I also beleived so.

     

    So, according to my file organization, do you have any idea about how to trigger/call the my_error_handler( ) function to handle the errors, which is established in the configuration script? For example, how can we call it in the index.php page (view all posts created and posted by all users of the forum)  in case that we have any error in the query ($q ="SELECT ...";) within the page's content section, while the configuration file has already been in the header section?

     

    Sorry if my explanation is still vague to you.

  2. Sorry for late response, but I was really busy in the last few weeks.

     

    Ok. To be short, let me briefly show you the codes of my pages as follows:

     

    1/ Index.php page:

    <?php
    
    Include the header
    include ('includes/header.html');
    
    //codes to show/echo the page content
    <p> bla bla </p>
    
    //Include footer
    include ('includes/footerl.html'); 
    ?>
    

    2/ The header.html file:

    <?php
    //start a session
    session_start();
    
    // Include the configuration file:
    require ('includes/config.inc.php');
    
    // Get the words for this language:
    require (MYSQL);
    
    //include lang choice
    require ('includes/languages.inc.php');
    
    ?>
    
    <!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">
     <head>
            <title><?php echo $page_title; ?> </title>
    </head>
    
    <body>
       <p> neccessary items for header part. </p>
    

    3/ footer.html file

    </body>
    </html>
    <?php // Flush the buffered output.
    ob_end_flush();
    ?>
    

    In the header.html file, you can see that I included the config.inc.php, which is the copied one of yours, and the languages.inc.php, which  stores and retrieves the language ID as your script 17.1.php does. This languages.inc.php does not need the database connection because the database connection had been included in the config.inc.php (define ('MYSQL', './database/mysqli_connect.php');, which goes before this file in the header.html

     

    In my every query to SELECT, INSERT INTO, DELETE, ect in the main pages such as register.php, view_posts.php, ect, I include the the error trigger ( 'or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc)); ') right in the $result=....;

     

    And I try testing by purposedly adding error into the code so that it would send to my assigned email address, but it didn't. The error returned directly in browser.

     

    Can you help?

     

    Thanks a lot!

  3. Yes, you are right. And I also tried it. You know what? When i define the location of the MySQL connection script in the config.inc.php, using script 16.1, along with the script mysqli_connect.php in Ch 18 for it, the error occurs like this '... on line 15: Constant LIVE already defined'. I know, it's an error!. Then, I commented out the mysqli_connect.php, it requires me to RE-CODE all the files that I used Procedural so far which would take me lots of time.

     

    Do you have any suggestion? because I have to switch to OOP gradually one by one, and the config.inc.php is included in the hear.html file, but not in seperate files. Or should I switch to OOP just because of the point in your book saying that it may be more secure and faster?

     

    Thanks

  4. I have made no change to the codes. As my header.html has two languages, I have to include the config.inc.php because the config.inc.php file defines the location of the MySQL connection script, mysqli_connect.php. Without this step, my header.html cannot function and cannot print the languages repectively, either.

     

    The difference between yours and mine is that you include the config.inc.php in the individual .php files along with the code of 'require (MYSQL); ' when you make the query for the tasks; whereas I include them in the header file only.

     

    The similarity between yours and mine is that we both use the error trigger ( 'or trigger_error("Query: $q\n<br />MySQL Error: " .
    mysqli_error($dbc)); '
    ) right in the $result=....;

     

    In my opinion, if we include the config.inc.php, the error handler should(must) be called because it has been really really included in it.

     

    Everything goes smoothly for me. However, the question in my head is that why does it not send the errors, if any as i test the writing scripts, to my defined email, but print it on the browser as if the error_handler function in the config.inc.php file was ignored.

     

    Does it technically ignore the error_handler function if it's not included directly in the writing file, to your coding experience? or what?

     

    I am confused/concerned about whether php programming language itself ignores the function that is included in the 'included' file?

  5. Hi everyone,

     

    As my header.html included file needs to connect to the dadabase for retrieving data, I have to include the config.inc.php script (18.3) in it, but not the individual file, e.g., register.php, etc, as per the chapter 18 outlines. You know, the errors directly display on the web browser instead of being sent to the defined email.

     

    Do you know why? And how can I get it sent to as per the my_error_handler function triggers?

     

    Note: In my .ini file, I changed the error_reporting  to  E_ALL, and log_errors to on , and I am not sure if these changes caused the problem or not?

     

    Can you help?

     

    Thanks

  6. Hi Larray and all,

     

    I have edited this script to fit my project, which I cut off the first name and last name. I added the username field which looks like this:

    <form action="" method="post">
          <fieldset>
            <legend>Sign Up </legend>
            
            <label>Choose a username</label>
            <input type="text" name="username" size="20" maxlength="20" value=" <?php if (isset($trimmed['username'])) echo $trimmed['username']; ?>" />
            
           <label>Email</label>
           <input type = "text" name="email" size="30" maxlength="60" value ="<?php if(isset($trimmed['email'])) echo $trimmed['email']; ?>" />
            	
            <label>Select a password</label>
            <input type="password" name="password1" size="20" maxlength="20" value="<?php if(isset($trimmed['password1'])) echo $trimmed['password1']; ?>" />
            	
            <label>Confirm password</label>
            
             <input type="password" name="password2" size="20" maxlength="20" value="<?php if(isset($trimmed['password2'])) echo $trimmed['password2']; ?>" />
    	
        <input type = "submit" name="submit" value="Sign Up "/>
           
        </fieldset>
        </form>
    

    I followed the script 18.6 strickly, plus do the username validation like this (of course, I also initiate the $errors = array(); too:

    //validate the username
    	if (preg_match('/^\w\S{2,20}$/', $trimmed['username']) ) {
    		$u = mysqli_escape_string($dbc, $trimmed['username']);
    	} else {
    		$errors[] = 'Please enter a username';
    	}
    

    Assume that other variable validations are okay. I code like this:

    if($u && $e && $p){//OK
    	
    		// Check for unique username and email
    		$q = "SELECT user_id from users where username='$u' AND email='$e'";
    				
    		$r = mysqli_query($dbc, $q) or die("MySQL error: " . mysqli_error($dbc) . "<hr>\nQuery: $q");
    		
    		if(mysqli_num_rows($r) == 0 ){
    
                          // Create the activation code
    			$a = md5(uniqid(rand(), TRUE));
    			
    			//Defined variable for language ID
    			$l = $_SESSION['lid']; //retrieved already in the header
    			
    			//Insert into database, table users
    			$q = " INSERT INTO users (lang_id, username, pass, email, active, registration_date)
    				   VALUES ('$l','$u', SHA1('$p'), '$e', '$a', NOW() )
    				 ";
    			$r = mysqli_query($dbc, $q) or die("MySQL error: " . mysqli_error($dbc) . "<hr>\nQuery: $q");
    			
       				if (mysqli_affected_rows($dbc) == 1) { // everything's ok
    					
    					//Send the email:
    					$body = "Thank you for your registration at askpro.com. To activate your account, please click on the link below \n\n";
    					$body .= BASE_URL. 'activate.php?e='.urlencode($e). "&a=$a";
    					mail($trimmed['email'], 'Registration Confirmation', $body, 'From: info@website.com');
    					
    					//Finish the page
    
    				echo '<h3>Thank you for registering! A confirmation email has been sent to your address. Please click on the link in that email  in order to activate your account.</h3>';
    				include ('includes/footer.html'); // Include the HTML footer.
    				exit(); // Stop the page.
    					
    				} else {
    					$errors[]='You could not be registered due to a system error. We apologize for any inconvenience.';
    				}
    				
    			
    		}else{
    			$errors[] = 'either the username or email has already been registered. If you have forgotten your password, use the link above to have your password sent to you.</';
    		}
    
    
    }else { // If one of the data tests failed.
    		echo 'Error:<br />';
    		foreach ($errors as $msg) { // Print each error.
    			echo "- $msg <br />";
    		}
    		$error[] =  'Please try again';
    	}
    
    }
    
    

    The question is that:

     

    -/ When I enter value and click the 'sign up' button with the intention that I enter a duplicate email, i.e., email@website.com, it returned error like this:

    MySQL error: Duplicate entry 'email@website.com ' for key 3
    ---------------------------------------------------------
    Query: SELECT user_id FROM users WHERE (username = 'dsfdsf' AND email = 'e')
    

    -/ Then I change the query to:

     

    $q = "SELECT user_id from users where username='$u' OR email='$e'";

     

    It returns NO error, but it does not insert anything into the database, and no 'thank you message' is printed.

     

    Can you help me to figure this out? Am I doing anything wrong? Thank you.

     

    P/S: This is my users table:

     

    h3PBk.gif

  7. I just had a problem with charset utf8 for my script 17.7.php

     

    I add this into my connection script (mysqli_connect.php) as per the book guilde

    mysqli_set_charset($dbc, 'utf8');
    

     And my live server is shared linux with Godaddy.com.

     

    The storage engine i am using is MySIAM, and the collocation is 'utf8_general_ci' and the PHP Version is 5.3.24

     

    The form is also coded to accept utf8 one more time like this:

    <form action="" method="post" accept-charset="utf-8">
    

    And the header .html file is also the same as the book guilde which includes this:

    header ('Content-Type: text/html; charset=UTF-8');
    

    When I validate the form, using htmlentities for the textarea field as $body = htmlentities($_POST['body']);

     

    When I enter my language, Vietnamese, i.e. đình, it  is converted to something like Ä

     

    If I exclude the htmlentities function, it becomes normal.

     

    So, How can I validate it using the htmlentities function for other languages beside English, as htmlentities will protect the form from hacking or so? or should I use another function?

     

    Thank you

  8. Hi HarleySan,

     

    This is my form:

    <?php
          echo '<form action="" method="get">
            <select name="lid" id="sel_lang">
              <option value="0">' . $langs['lang'] . '</option>';
              
     // Retrieve all the languages...
    $q = "SELECT lang_id, lang_others FROM languages ORDER BY lang_eng ASC";
    $r = mysqli_query($dbc, $q);
    if (mysqli_num_rows($r) > 0) {
      while ($menu_row = mysqli_fetch_array($r, MYSQLI_NUM)) {
        echo "<option value=\"$menu_row[0]\">$menu_row[1]</option>\n";
      }
    }
    mysqli_free_result($r);
    
            echo '</select>
            <input name="submit" type="submit" value="'. $langs['go']. '" />
          </form>';
    mysqli_close($dbc);    //Close the database connection.
    ?>
    

    Can you help, pls?

  9. Hi Larry cc all,

     

    1/ Regarding to the script 17.7, which uses the mysqli_insert_id() function when the new thread/ subject is created. My question is why should we apply this function for the $tid variable in this scenario - if(!$tid){...} - instead of echoing/ printing a message informing the users that the new subject is successfully created? because when the new subject/record is inserted into the threads table, the new thread_id will be automatically generated as the next highest interger, and inserted into the AUTO_INCREMENT field for this one, which should be greater than zero that satisfies the thread ID validation condition (..., FILTER_VALIDATE_INT, array('min_range' => 1) )

     

    2/ Regarding to the issue of multiple query execution, suppose that I seperate the threads table columns into two tables like this:

     

    a/ subjects table:

    $query = 'CREATE TABLE subjects (
                subject_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
                lang_id TINYINT(3) UNSIGNED NOT NULL,
                user_id INT UNSIGNED NOT NULL,
                subject VARCHAR(150) NOT NULL,
                PRIMARY KEY (subject_id),
                INDEX (lang_id),
                INDEX (user_id)
                ) ENGINE = MYISAM';

    == =

    b/ messages table:

     

    $query = 'CREATE TABLE messages (
                messages_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
                subject_id INT UNSIGNED NOT NULL,
                user_id INT UNSIGNED NOT NULL,
                message TEXT NOT NULL,
                posted_on DATETIME NOT NULL,
                PRIMARY KEY (messages_id),
                INDEX (subject_id)
                ) ENGINE = MYISAM';

     

    And assume that the other two tables of users and languages remained unchanged.

     

    => Now, I execute multiple queries to insert values for these two tables at the same time, which I go like this:

    if (!sid) {

            $q = "INSERT INTO subjects (lang_id, user_id, subject)

                    VALUES ({$_SESSION['lid']}, {$_SESSION['user_id']}, '" . mysqli_real_escape_string($dbc, $subject) . " ');";

     

           $q .="INSERT INTO messages (subject_id, user_id, message, posted_on)

                    VALUES ({$sid, {$_SESSION['user_id']}, ' " . mysqli_real_escape_string($dbc, $body) . " ', UTC_TIMESTAMP() );";

     

    $r = mysqli_multi_query($dbc, $q);
                    if (mysqli_affected_rows($dbc) == 1) {
                        
                        echo '<p> Your new subject and message have been posted successfully</p>';
                        
                    } else {
                        echo '<p> Your new subject and message could not be handled because of system error. </p>';
                    }

    } // end of if(!$sid)

     

    Note: $sid variable stands for subject_id and $body variable stands for message.

     

    I obmit the $sid = mysqli_insert_id($dbc); after the mysqli_affected_rows($dbc) == 1 because i am waiting for the discussions and answers for question# 1 above.

     

    And I use the value $sid for the column subject_id of the messages table in the second query because I think that it goes after the first query for the subjects table, of which the new result/row has just been affected and inserted.

     

    Sorry but am I correct?

     

    I am expecting all of your ideas and discussion.

     

    Thanks in advance.

  10. @Larry: as you see, when we create a new column for the words table, called newcol, its records/ rows in the order of lang_id is empty. Now, we insert values into these respective two rows, one is in the default language, English, and the another is in my language, Vietnamese.

     

    1/ If I use this query:

     

    $query = "INSERT INTO words(word_id, lang_id, newcol)
                   VALUES
                (NULL, 1, 'english_value'),
                (NULL, 2, 'vietnamese_value')
                ";

    It will insert the next row for word_id column, because word_id is the AUTO_INCREMENT column.

     

    2/ because of the 1) above, I omit the word_id, and lang_id, to use this query:

     

    $query = "INSERT INTO words (newcol)
                   VALUES
                ('english_value'),
                ('vietnamese_value')
                ";

     

    It will return syntax error like this: Could not insert into the table because: Duplicate entry '0' for key 2.

     

    When I checked the result table, you know, it created the new row for word_id with the first value inserted.

     

    3/ Then I try the original syntax shared above in the original post with using the ON DUPLICATE KEY UPDATE, but i failed.

     

    => finally, i got stuck there.

     

    So, can you grab my idea here, and show me how to do it?

     

    appreciated!

  11. @ indigetal: Your reply is appreciated. However, what i'd like to mention (and also discuss) here is that how to insert two values/ rows into one single column of the table that companions with the UNIQUELY indexed column, lang_id?

     

    P/S: I also tried the following syntax:

    $query = "INSERT INTO words (lang_id, newcol) VALUES (1, 'newvalue1'), (2, 'newvalue2')

     

    ON DUPLICATE KEY UPDATE newcol= VALUES(('newvalue1'),('newvalue2'))

    ";

     

    But it failed :-( and returned the message like this:

     

    Could not insert into the table because:
    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '('newvalue1'),('newvalue2')
    at line 5.

  12. Regarding to the words table, I would like to play around by adding one (or more columns) with respective values into it by applying these two blocks of code:

     

    Code 1:

    // Add a new column:

     

    $query = 'ALTER TABLE words
                 ADD COLUMN newcol VARCHAR(255) NOT NULL
                ';

     

    And then I went to add values for it which must match the lang_id unique column, right?

     

    Code 2:

     

    // insert values into it:

     

    I followed the syntax sample as shown in the book, I applied this one:

     

    $query = "INSERT INTO words (lang_id, newcol) VALUES (1, 'newvalue1'), (2, 'newvalue2')";

     

    As you can see that the lang_id is the UNIQUE indexed one, so I did like this:

     

    $query = "INSERT INTO words (lang_id, newcol) VALUES (1, 'newvalue1'), (2, 'newvalue2');

     

    ON DUPLICATE KEY UPDATE newcol = 'newvalue1, newvalue2' ";

     

    It worked fine to me.

     

    However, when I viewed the result table, the two records/rows for the newcol column were updated with the newvalue2 only.

     

    So, the question is how can I insert the two new values into this single new column which should go exactly into the respective lang_id, 1 and 2, as it should be?

     

    Your answers will be very much appreciated!

     

    Note: ON DUPLICATE KEY UPDATE is not mentioned in any original codes in the book, nor does the book mention about it. I've searched around about it. So, it's not the perfect one, i guessed.

  13. Another curious question about activation code is that I have seen some websites that enable the users to activate their new accounts by entering the random code received via cell phone numbers registered during the 'sign-up' process, which i think that it is quite fast, handy, and even secure (if I were wrong).

     

    Have you got any book instructing this, Larry?

     

    And do you guys know any resources about this to share?

     

    Thanks,

    Eric

  14. Yes, they can be regarded as valid ones.

     

    In my opinion, a valid email address can be seen as any kind of vertical address (to compare to a physical home address) that someone creates for his contact with other people and that it is also a method of exchanging digital messages one another. So, as long as it meets the universal and programmatic structure of only one @ sign and at least a . (dot) after it, it is considered as a valid one.

     

    And a valid email address could never be a dead one, but an alive one. I mean that the valid email address means nothing to computers, but it means something to human being.

     

    Therefore, your host company (human being) may think that different people refer to have different kinds of email addresses. So they tolerate the use of non-alphanumeric characters, and ask computers (machine) to accept it.

     

    So, as a programmer, I think, when he wants to validate a valid email address, he must:

     

    1/ validate and sanitize the email structure syntactically (there is no more than @ sign or so in the structure).

    2/ ask the email users or email servers to confirm the validity and reality of the email (there is at least one person possessing it).

     

    Then he is successful....right?

    • Upvote 1
  15. To discuss further away from the topic and the book's content, but in the same area, I happened to see this website: http://tools.email-checker.com/

     

    Do you think that PHP can perform the same tasks as that website does? If yes, do you have any book about this, Larry? or do you know any online resources to point to so that I can learn more and share more about it?

     

    Eric

  16. Hi Larry,

     

    Your pattern ^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$ provides for reasonably good email validation. However, your tip #2 warns that it will allow some invalid addresses to pass through (like ones starting with a period or containing multiple periods together). So, can I eliminate this by going with the word boundaries like this: \b[\w.-]+@[\w.-]+.[A-Za-z]{2,6}\b

     

    If you, and other forum participants, also find it 'not good at all' or 'worse than the original one', please share your ideas and reasons as I really want to strive for the better one for it.

     

    Thanks in advance.

     

    Eric

  17. I have a question about email matching with regular expressions. 

     

    Chapter 14, Pg. 445, contains the following email matching pattern:

     

    ^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$

     

    I may be wrong, but wouldn't it match something like this?

     

    somename@some_website.com

     

    I would say 'no, it would' because the shortcut \w after @ certainly does allow (and match with) letters, numbers and underscore, according to the PHP manual. So, we cannot remove the underscore if we still want to use \w immediately after the @ sign.

     

    if you don't really want the underscore after the @ sign, you may follow the HartleySan's character class, [A-Za-z0-9]. However, this character class will stop such a valid email as somename@some-website.com as it contain a dash (-).

     

    So, to my understanding of this topic, if we want to validate/ allow any words, numbers, hyphen, but not underscore between the @ and . in an email address as per the original quest of the 'perfect' one, we can only go with the class like [- A-Za-z0-9] or [A-Za-z0-9 -] (it does no harm if you want to escape the hyphen as per Larry's syntax above)

     

    Besides, we can test the other class like [\w.-]+[^\_] between the @ and .

     

    Hope this may help!

×
×
  • Create New...