cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, have you tried the solution offered in their forum? Here's the link:

cereal 1,524 Nearly a Senior Poster Featured Poster

The date_diff() function requires two arguments, also both must be resources of the DateTimeInterface, if you pass a string, as in your example, the function will fail.

So, you must write:

<?php

    $date_a = '2015-04-01';
    $date_b = '2015-03-25';

    $dt_a = new Datetime($date_a);
    $dt_b = new Datetime($date_b);

    $interval = date_diff($dt_a, $dt_b);
    echo $interval->format('%R%a days'); # -7 days

Or use the object style, like your previous example. Note that the result is an object that cannot be converted directly to a string, so you must use the format() method.

cereal 1,524 Nearly a Senior Poster Featured Poster

Try if it works fine from the mysql client, because it returns this error to me:

ERROR 1414 (42000): OUT or INOUT argument 2 for routine dbase.test_proc is not a variable or NEW pseudo-variable in BEFORE trigger

You can try to bypass the error by setting a variable before calling the procedure, like this:

DROP PROCEDURE IF EXISTS test_proc;
DELIMITER $$
CREATE PROCEDURE `test_proc`(In user_id varchar(100), OUT message varchar(1000))
BEGIN
 set message ='OK';
END $$
DELIMITER ;

-- as suggested here: https://bugs.mysql.com/bug.php?id=25970#c195094
SET @test = 'world';
CALL test_proc('hello', @test);
SELECT @test;

In PDO this becomes:

<?php

    $conn = require './pdo.php';

    $ret = 'world';
    $sso = 'hello';

    $stmt1 = $conn->prepare("SET @test = ?");
    $stmt1->execute(array($ret));

    $stmt2 = $conn->prepare("CALL test_proc(?, @test)");
    $stmt2->execute(array($sso));

    $query = $conn->query("SELECT @test as result")->fetch(PDO::FETCH_OBJ);

    echo $query->result;

Which seems to return fine to me: OK.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, open the Developer Tools console in Google Chrome, then click on the smartphone icon, it allows to test some device resolutions, here's a screenshot:

http://i.imgur.com/cs3ZeA7.png

diafol commented: Great advice +15
cereal 1,524 Nearly a Senior Poster Featured Poster

In addition, if you're using Laravel, then you can use the asset() helper:

$link = asset("/images/Work_Anniversary.png");

This will prepend the application url.

cereal 1,524 Nearly a Senior Poster Featured Poster

Try to change the header to:

curl_setopt($curl, CURLOPT_HTTPHEADER, array(
    "Authorization: Token token=$token"
));

Then it should work fine. To debug the request add:

curl_setopt($curl, CURLINFO_HEADER_OUT, true);

And:

$info = curl_getinfo($curl, CURLINFO_HEADER_OUT);

Which prints:

GET /api/v1/items/8568ccd0-c614-012f-1d74-58d385a7bc34.json HTTP/1.1
Host: api.repo.nypl.org
Accept: */*
Authorization: Token token=YOUR_TOKEN
cereal 1,524 Nearly a Senior Poster Featured Poster

@Nilo, do:

$row = $conn->query("SELECT MAX(id) AS last_id FROM Posts")->fetch(PDO::FETCH_OBJ);
echo $row->last_id;

It's important to define an alias MAX(id) AS last_id otherwise you get:

stdClass Object
(
    [MAX(id)] => 100
)

Which can be accessed with another syntax:

echo $row->{'MAX(id)'};
cereal 1,524 Nearly a Senior Poster Featured Poster

If there are not previous insert queries, then lastInsertId() will return 0, for this reason the loop does not run.

The MySQL documentation explains the reason:

The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.

Link: https://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-insert-id

To get the last id you can do:

SELECT MAX(id) FROM tablename;

A consideration about the loop: if you delete one of the previous rows then you will get some errors, for example:

> select id from tablename;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
+----+

> delete from tablename where id = 2;

> select max(id) as last_id from tablename;
+---------+
| last_id |
+---------+
|       5 |
+---------+

The last id will always be 5, MySQL will not scale the values to occupy the missing row. As result, the loop will go through the id with value 2 even if it does not exists anymore. It's better to get the list of the …

cereal 1,524 Nearly a Senior Poster Featured Poster

I suppose you're using this plugin: http://jqueryvalidation.org/

If yes, then it seems you can define only one validation process for the chosen form, so don't set two of them:

$('#DemoForm').validate({
    rules:{},
    messages:{}
});

$('#DemoForm').validate({
    rules:{},
    messages:{}
});

Set only one for this ID. The second problem is given by the value assigned to the required attribute which needs to be boolean, not string. So, instead of:

required:"true",

Use:

required:true,

The same applies to the other attributes in which you define a boolean value, like email:

email:true,

Full example:

<!DOCTYPE html>
<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
        <title>jQuery Form Validation</title>
    </head>
    <body>

        <form method="post" action="jTest5.8.html" id="DemoForm" name="DemoForm">

            Username<br />
            <input type="text" id="user_input" name="username" /><br>

            Email<br />
            <input type="text" id="email" name="email" /><br>

            Password<br />
            <input type="password" class="form-control" name="password" id="password"/><br>

            Password Again<br />
            <input type="password" class="form-control" name="cfmPassword" id="cfmPassword" /><br>

            <input type="submit" value="submit"/>

        </form>

        <script src='jquery.validate.min.js'></script>    
        <script>
            $("#DemoForm").validate({
                rules: {
                    'email': {
                        required: true,
                        email: true,
                        },

                    'password': {
                        required: true,
                        minlength: 6,
                        maxlength: 10,
                        },

                    'cfmPassword': {
                        equalTo: "#password",
                        minlength: 6,
                        maxlength: 10
                        }
                    },

                messages: {
                    'email': {
                        required:'Please submit your email.',
                        email:'Enter a valid email.',
                        },
                    'password': {
                        required:"The password is required"
                        }
                    }
            });
        </script>

    </body>
</html>

Which should work fine.

mattyd commented: Thank you for all your help on this! +0
cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, I think you have to fix the opening form tags, at the moment you have three of them, the first is not closed and it will lead to some errors:

<form id="DemoForm"

The second is well defined:

<form method = 'post' action = 'jTest1.8.html' id = 'DemoForm' name = 'DemoForm'>

The third is going to submit a GET request:

<form id="formCheckPassword">

Because the method is not defined and the default setting is to play GET.

When you submit the form, only the values of the third form will be submitted because these are contextual to the submit button, to include the input fields of the second form, you have to merge them into a single form:

<form method="post" action="jTest1.8.html" id="DemoForm" name="DemoForm">

    Username<br />
    <input type="text" id="user_input" name="username" /><br>

    Email<br />
    <input type="text" id="email" name="email" /><br>

    Password<br />
    <input type="password" class="form-control" name="password" id="password"/><br>

    Password Again<br />
    <input type="password" class="form-control" name="cfmPassword" id="cfmPassword" /><br>

    <input type="submit" value="submit"/>

</form>

Fix also the javascript validation rules, to match the same form ID, or simply merge them and you're finished.

mattyd commented: Thank you. I will work on this later and post the results here. +0
JorgeM commented: yep! +12
cereal 1,524 Nearly a Senior Poster Featured Poster

It happens when you use the GET method, use POST instead.

mattyd commented: Thank you! +8
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi!

That's the format supported by the database, save it like this, then when your get the result set format as you prefer. You can do it directly at query level with the format_date() function:

or in PHP with the IntlDateFormatter class:

For this task I use a little class, that can can convert also to a more readable format and display the month name in the language you prefer. Here's the code:

<?php

    class Dtime extends IntlDateFormatter
    {
        private $date;

        public function __construct($datetime = '', $pattern = 'd MMMM yyyy HH:mm', $locale = 'it')
        {
            parent::__construct($locale, IntlDateFormatter::FULL, IntlDateFormatter::FULL);

            $this->date = new DateTime($datetime);
            parent::setPattern($pattern);
        }

        public function get()
        {
            return mb_convert_case(parent::format($this->date), MB_CASE_TITLE, "UTF-8");
        }
    }

By default the language is set to Italian, but this can changed, as the format, usage example:

$date = '2015-04-14 21:00';
$dt   = new Dtime($date, 'dd-MM-yyyy', 'it');
echo $dt->get();

Which returns 14-04-2015, the default setting:

$date = '2015-04-14 21:00';
$dt   = new Dtime($date);
echo $dt->get();

returns:

14 Aprile 2015 21:00

There are also other methods to format a date, you can use the DateTime class or the strtotime() function:

Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, I got it, your code is perfect, the issue is in my logic.

By starting everything by zero I wasn't considering that when the $pages variable was divisible by $perpage (e.g. 100 / 10) the result would be 10, but the last range would be LIMIT 90, 10 at page 9, the issue happens because there is an extra query that sets the range LIMIT 100, 10 at page 10 and because the ELSEIF stop condition was current_page >= total_pages, which at the end translates to 10 >= 10 when, by starting from zero, it should have been 10 >= 9.

I was tricked by the $perpage set at three: the last page is 33 which generates LIMIT 99, 3 and returns only the last row which, in appearance, is correct.

It can be fixed to continue the script starting at zero, but at this point I think it is a better to start everything from one. I updated your last code, you can try it here:

And here's your code (updated):

<?php

    $servername = "localhost";
    $dbname     = "test";
    $dbusername = "root";
    $dbpassword = "";
    $error      = FALSE;
    $result     = FALSE;

    try {
        $conn = new PDO("mysql:host=$servername;dbname=$dbname", $dbusername, $dbpassword);
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $total = $conn->query("SELECT COUNT(id) as rows FROM Posts")
                 ->fetch(PDO::FETCH_OBJ);

        $perpage = 3;
        $posts   = $total->rows;
        $pages   = ceil($posts / $perpage);

        # default
        $get_pages = isset($_GET['page']) ? $_GET['page'] : 1;

        $data = array(

            'options' => array(
                'default'   => 1,
                'min_range' => 1,
                'max_range' => $pages …
cereal 1,524 Nearly a Senior Poster Featured Poster

Why you set $error = FALSE; and $result = FALSE; to False?

This is done to initialize the variables in my test script, otherwise if the database fails for some reason (no connection, query error) then PHP will show this notice:

Severity: Notice
Message: Undefined variable: result

by simply setting the variable $result = FALSE; PHP will run the code into the IF statements and will find other variables not initialized like $pages, $number, $next and $prev, also the loop at line 181 will fail. To avoid most of these errors I could do:

$pages  = FALSE;
$number = FALSE;
$next   = FALSE;
$prev   = FALSE;

But the loop warning will still remain:

Invalid argument supplied for foreach()

Why? Because of this:

$result = FALSE;
var_dump(count($result)); # int(1)

It returns 1, so the IF statement:

if(count($result) > 0)

Will fail, and it is not fixable by changing the condition to 1:

if(count($result) > 1)

because the query could return only one post. So to avoid the warning all you have to do is to verify if the variable is not FALSE. In my test script my check is implicit, this:

if($result)

Is equal to write:

if($result !== FALSE)

Note if you write:

if($result === TRUE)

The warning will disappear in case of database fails, but when the query works well it will not show any results because the types are different: $result will be an array and TRUE is …

cereal 1,524 Nearly a Senior Poster Featured Poster

No problem & happy holidays ;)

It can be done with MySQLi but you're mixing procedural and object oriented (OOP) styles.

In OOP the connection is open like this:

$db = new mysqli(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_DATABASE);

Then you can use $db to run the methods. MySQLi hasn't defined a fetch() method, in your case you would use fetch_object():

$row = $db->query('SELECT name FROM countries WHERE country_id = 15')->fetch_object();

echo $row->name;

Also: the query() method accepts a second argument, but this is used to define the result mode, here you can find some information about these modes:

For a list of fetch modes, instead, check the methods defined for the mysqli_result class:

cereal 1,524 Nearly a Senior Poster Featured Poster

Hmm, no I don't think so. I wrote a test script, check if it works for you:

<?php

    $servername = "localhost";
    $dbname     = "mydbname";
    $dbusername = "mydbusername";
    $dbpassword = "mydbpassword";
    $error      = FALSE;
    $result     = FALSE;

    try {
        $conn = new PDO("mysql:host=$servername;dbname=$dbname", $dbusername, $dbpassword);
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $total  = $conn->query("SELECT COUNT(id) as rows FROM Posts")
                  ->fetch(PDO::FETCH_OBJ);

        $perpage = 3;
        $posts   = $total->rows;
        $pages   = floor($posts / $perpage);

        # default
        $get_pages = isset($_GET['page']) ? $_GET['page'] : 0;

        $data = array(

            'options' => array(
                'default'   => 0,
                'min_range' => 0,
                'max_range' => $pages
                )
        );

        $number = trim($get_pages);
        $number = filter_var($number, FILTER_VALIDATE_INT, $data);
        $range  = $perpage * $number;

        $prev = $number - 1;
        $next = $number + 1;

        $stmt = $conn->prepare("SELECT ID, Author, Content FROM Posts LIMIT :limit, :perpage");
        $stmt->bindParam(':perpage', $perpage, PDO::PARAM_INT);
        $stmt->bindParam(':limit', $range, PDO::PARAM_INT);
        $stmt->execute();

        $result = $stmt->fetchAll();

    } catch(PDOException $e) {
        $error = $e->getMessage();
    }

    $conn = null;
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>User View Page</title>
        <style type="text/css">

            body {
                font:1rem Arial,sans-serif;
                color:#1a1a1a;
            }

            a {
                text-decoration:none;
                color:#4281A4;
                transition: .3s color;
            }

            a:hover {
                color: #314CB6;
            }

            .error {
                width:100%;
                padding:.5em;
                background-color: #D7F75B;
            }

            .navigation span,
            .navigation a {
                display: inline-block;
                padding:0.5rem;
            }

            #wrap {
                margin:50px auto;
                width: 960px;
            }

            table {
                width:100%;
                border-collapse:collapse;
            }

            th {
                text-align:left;
            }

            tbody > tr:nth-child(odd) {
                background:#f3faf1;
            }

            tbody > tr:nth-child(even) {
                border-top: 1px solid #e5e5e5;
                border-bottom: 1px solid #e5e5e5;
            }

            td:first-child {
                width:25px;
            }

            td:nth-child(2) {
                width:10%;
            }

            thead th,
            tbody td {
                padding:.5rem;
                line-height:1.4rem;
            }

        </style> …
cereal 1,524 Nearly a Senior Poster Featured Poster

Whoops! I'm sorry, I did a mistake when I defined the default values, change lines from 11 to 19 with this:

$get_pages = isset($_GET['page']) ? $_GET['page'] : 0;

$data = array(

    'options' => array(
        'default'   => 0,
        'min_range' => 0,
        'max_range' => $pages
       )
);

And in the HTML part change this condition:

if($number <= 1)

To:

if($number <= 0)

So, when ?page= is not defined or is 0 it will return 0,3 i.e. the first three posts, page=1 will return 3,3, page=2 will return 6,3 and so on... I think it should work fine now.

Going to your questions:

What does floor do here?

$pages = floor($posts / $perpage);

Floor is a function to round fractions down, if you do 15 / 2 you get 7.5, by using floor you get 7, you can decide to round always up by using ceil() or to depend on the value with round() ( by default this function rounds down when the decimal is .4 or lower, with .5+ rounds up), for example:

$n = 15 / 2;
echo floor($n); # 7
echo ceil($n);  # 8
echo round($n); # 8

In this case, if we round up, the last page will be empty.

Docs:

What does this line say?

This line is an IF statement, defined with the ternary operator ?::

$get_page = isset($_GET['page']) ? $_GET['page'] : 0;

It is a short …

cereal 1,524 Nearly a Senior Poster Featured Poster

The trim() function is used to remove leading and trailing spaces, for example:

$a = ' 1';
var_dump($a);

Outputs: string(2) " 1", instead:

$b = trim($a);
var_dump($b);

Outputs: string(1) "1"

As you see, it removes the extra space, but it returns always a string, not an integer type, to get an integer you can do:

$c = (int)$b;
$d = intval($b);

But you still need to validate the input, so in this case you can use filter_var() where:

  1. the first argument is the string;
  2. the second argument is a constant to define the type of validation or sanitazation;
  3. the third argument in this case is an array with a default value, in case the user submits something else, like a negative number or word values, and it is useful if you want to stop at a defined value.

So:

$e = filter_var($b, FILTER_VALIDATE_INT);

In all these cases ($c, $d and $e) var_dump will return:

int(1)

Not anymore string. Some information here:

I want each page to show only 3 posts to the user, so posts 1-2-3 go into page 1, and posts 4-5-6 go into page 2, and posts 7-8-9 go into page 3.

Now, what you're searching for is pagination. In practice you have to define how many posts you want to display for each page, in your case 3, so we need to define the boundaries, …

cereal 1,524 Nearly a Senior Poster Featured Poster

My fault, sorry: you have to pass an integer to the bind method, from the form it receives a string and so the query will output badly, something like:

LIMIT "1', 3'"

I was testing from command line. Add the filter_var() and it will work properly:

$number = trim($_POST['number']);
$number = filter_var($number, FILTER_VALIDATE_INT);

$stmt = $conn->prepare("SELECT ID, Title, Author, Content FROM Posts LIMIT :limit, 3");
$stmt->bindParam(':limit', $number, PDO::PARAM_INT);

In addition, with the filter_var() function you can define a range of valid values, for example:

$data = array(
    'options' => array(
        'default'   => 1,
        'min_range' => 1,
        'max_range' => 100
       )
);

$number = filter_var($number, FILTER_VALIDATE_INT, $data);

Last, add the name attribute to your submit button, otherwise this statement if(isset($_POST['submit'])) will fail:

<input type="submit" name="submit" value="Submit">
cereal 1,524 Nearly a Senior Poster Featured Poster

It returns boolean (FALSE in this case) because the query will generate an error, due to a quote placed in the wrong place s.type='c)', so change this:

$sql = "SELECT s.*, u.avatar 
    FROM status AS s
    LEFT JOIN users AS u ON u.username = s.author
    WHERE (s.account_name = '$u' AND s.type='a') 
    OR (s.account_name='$u' AND s.type='c)'        -- error
    ORDER BY s.postdate DESC LIMIT 20";

To:

$sql = "SELECT s.*, u.avatar 
    FROM status AS s
    LEFT JOIN users AS u ON u.username = s.author
    WHERE (s.account_name = '$u' AND s.type='a') 
    OR (s.account_name='$u' AND s.type='c') 
    ORDER BY s.postdate DESC LIMIT 20";

Since you're using MySQLi consider to use prepared statements, for some examples check this thread:

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, if country_id is unique then you don't need the limit statement. Use mysql_fetch_row() instead of mysql_fetch_array(), but you really should not use these function anymore, these are deprecated and will be removed. With PDO you can do:

$row = $pdo->query('SELECT name FROM countries WHERE country_id = 15', PDO::FETCH_OBJ)->fetch();

echo $row->name;
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

just a note: the mcrypt_ecb() function is deprecated since PHP 5.5, it means this is going to be removed. You should use mcrypt_generic()and mdecrypt_generic() as explained in the documentation:

For some information about the encryption modes check those available:

I would use CBC rather than EBC, because with EBC is possible to find patterns and it is possible to alter the encrypted string to obtain something else. This article explains the issue very well:

Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi all,

@slowlearner2010

just for the log, it seems you don't need the array_push() neither the loop, use trim() to remove extra spaces and then use implode(), then you should be done:

$a = array_map('trim', $_POST['a']);
$b = implode(',', $a);

At least, looking at your example, this seems to work fine. Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

It happens because you're missing the quote for the previous values, this:

('60', 'Ng\'wagindu),

should be:

('60', 'Ng\'wagindu'),
rch1231 commented: Good Eye. Was just ablut to say the same thing. +11
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, getimagesize() is a function to evaluate the pixels of an image, the type and the attibutes (a stringed version of height and width), it returns an array. For example:

Array
(
    [0] => 20
    [1] => 10
    [2] => 2
    [3] => width="20" height="10"
    [bits] => 8
    [channels] => 3
    [mime] => image/jpeg
)

So it is not directly used to upload an image, it is used to define the image type, and usually is used in the validation step, after the upload.

The file_get_contents() function is used to get the content from a file which can be locale or remote. The cURL library is used to perform requests to remote servers, which means it can be an upload to another server or a GET request to download an image from a remote resource (ftp, web server, API).

So the question is: are you trying to get the image from another server?

To upload an image from a client computer, instead, you need a form, basically:

<form method="post" action="upload.php" enctype="multipart/form-data"
    <label for="image">Upload an image</label>
    <input type="file" name="image" id="image" />
    <input type="submit" name="submit" />
</form>

And then, in the upload.php script, you have to check the contents of the $_FILES array:

print_r($_FILES['image']);

For more information check these docs:

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, if you're using a prepared statement to insert the data, then submit the zipcode as a string, not as integer, this should solve the issue for you. The table column must be char or varchar, as you're already doing.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi! In addition to Dave's suggestion, having a div between rows is not really correct:

<table>
    <tr>
        <td>

    <div class="img">
        <tr>
            <td><img src="..." />
    </div>

    <tr>
        <td>
</table>

Do:

<table>
    <tr>
        <td>

    <tr>
        <td><div class="img"><img src="..." /></div>

    <tr>
        <td>
</table>

Or simply:

<table>
    <tr>
        <td>

    <tr>
        <td><img class="img" src="..." />

    <tr>
        <td>
</table>

If necessary. Otherwise you can append the class to the td tag.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, it seems fine to me, but you can use directly the object created by the diff() method, without formatting the output, as in my previous example:

$minutes  = 0;
$minutes += $diff->h * 60;
$minutes += $diff->i;

echo round($minutes / 4);

Which outputs 23, with floor 22. If you do print_r($diff) you will see:

DateInterval Object
(
    [y] => 0
    [m] => 0
    [d] => 0
    [h] => 1
    [i] => 30
    [s] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 0
    [days] => 0
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

use the DateTime library, in particular look at the diff() method. For example:

<?php

    $one = '09:30AM';
    $two = '06:30PM';

    $dtime_1 = new Datetime($one);
    $dtime_2 = new Datetime($two);

    $diff = $dtime_1->diff($dtime_2);
    echo $diff->format('%H:%I');

Will print 09:00. More info here:

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi all,

James you can send an email to Gmail SMTP, you don't need sendmail to do this because you're going to connect directly to the SMTP server. Check this example:

Which makes uses of PHPMailer library:

You can do it without: you need to use PHP sockets and you have to create a script that listens to the replies of the SMTP server, otherwise it will not work. Using a library like PHPMailer is probably the best solution. Bye!

Kyle Wiering commented: Great post! +2
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, create a container for #box5, then you can use two methods.

Method 1

Move the text outside the opaque element and move it over, something like this:

<div id="box">

    <div id="box5"></div>

    <div id="box5-p">
        This text is normat text over opacity background
    </div>

</div>

Styles:

#box
{
    position: relative;
    width:250px;
    height:250px;
}

#box5 {
    margin:10px;
    width:100%;
    height:250px;
    border:1px solid green;
    overflow:auto;
    float:left;
    background-size:50%;
    background: url(https://developer.mozilla.org/media/img/mdn-logo.png);
    background-repeat:no-repeat;
    background-position:center;
    padding:20px;
    opacity: 0.2;
    z-index:99;
}

#box5-p {
    position: absolute;
    top:20px;
    left:20px;
    opacity:1;
    color:red;
    font-size:18;
    font-weight:bolder;
    z-index:100;
}

Live example: http://jsfiddle.net/qe3xpzhn/

Method 2

Use the #box5::after rule where you define the background and the opacity level, something like:

<div id="box">

    <div id="box5">
        This text is normat text over opacity background. This text is normat text over opacity background.
    </div>

</div>

And the styles:

#box
{
    position: relative;
    width:250px;
    height:250px;
}

#box5 {
    margin:10px;
    width:250px;
    height:250px;
    border:1px solid green;
    overflow:auto;
    position: relative;
    float:left;
    padding:20px;
}

#box5::after
{
    content: "";
    opacity:0.2;
    background-image:url(https://developer.mozilla.org/media/img/mdn-logo.png);
    background-repeat:no-repeat;
    background-position:center;
    background-size:50%;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    position: absolute;
    padding:20px;
    overflow:auto;
}

Live example: http://jsfiddle.net/2sc4zpjx/
Source: https://css-tricks.com/snippets/css/transparent-background-images/

mattster commented: +1 +7
cereal 1,524 Nearly a Senior Poster Featured Poster

In addition: $values['books'] is an array where the index key is the book_id, for example:

[books] => Array
    (
        [38] => Array
            (
                [book_id] => 38
                [title] => Alexander of Macedon, 356-323 B.C. : a historical biography.
                [author_lf] => Green, Peter
                [author_fl] => Peter Green
                [author_code] => greenpeter
                [ISBN] => 0520071654
                [ISBN_cleaned] => 0520071654
                [publicationdate] => 1991
                [entry_stamp] => 1124597764
                [entry_date] => Aug 21, 2005
                [copies] => 1
                [rating] => 5
                [language_main] => eng
                [language_secondary] => 
                [language_original] => 
                [hasreview] => 1
                [dateacquired_stamp] => 0
                [dateacquired_date] => Dec 31, 1969
                [cover] => http://pics.cdn.librarything.com/picsizes/44/87/448711e34ba0018597835424e67414141414141.jpg
                [bookreview] => This was my introduction to Alexander the Great. I still think it's the best, although Robin Lane Fox's...
                [bookreview_stamp] => 1229121379
                [bookreview_date] => Dec 12, 2008
                [tags] => Array
                    (
                        [0] => favorite
                        [1] => alexander the great
                    )

            )

So, to see the results you have to loop it:

foreach($values['books'] as $book_key => $book_value)
{
    echo $book_value['title'];
}
broj1 commented: Well spotted +11
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi all,

I still haven't tried PHPStorm as I usually prefer simple editors, among these I'm really happy with Sublime, right now.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

it could be the mime-type or the column table size, be sure to not truncate the input. If using a blob column type then this can support up to 65536 bytes. To save more data use mediumblob which supports up to 16MB or longblob which supports up to 4GB.

The same applies if you're saving them as encoded strings, use mediumtext or longtext instead of text.

Docs: http://dev.mysql.com/doc/refman/5.6/en/storage-requirements.html

cereal 1,524 Nearly a Senior Poster Featured Poster

Thanks for sharing! I tested your class and I like it, consider to add a passphrase to allow different results, it could be helpful.

You may want to check Hashids, it's very similar to your concept: http://hashids.org/

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

you actually get the result, just loop it:

$result = $pdo->query("SELECT * FROM posts");

foreach ($result as $key => $value)
    echo $value['title'];

echo 'Total: '. $result->rowCount();

It's not visible through print_r() because the statement is an iterable object, if you want the full array use fetchAll():

print_r($result->fetchAll());

As second parameter you can define the fetch mode, for example:

$result = $pdo->query("SELECT * FROM posts", PDO::FETCH_ASSOC);

For more information check the PDOStatement class:

Also, read the following article, at the end there is a paragraph dedicated to PDO::FETCH_CLASS method, which explains a bit how flexible can be a PDO statement:

lps commented: nice detailed explainations +4
terryds commented: Thanks for your nice answer +0
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, use trim() to remove the pending comma:

echo trim('a,b,c,', ',');

The same can be done at query level:

select trim(TRAILING ',' FROM 'a,b,c,');

Docs:

cereal 1,524 Nearly a Senior Poster Featured Poster

Yes you can, SimpleXML is going to create an object of that string, so it should be easy, for example:

print_r($xml->Course);

Or to get a specific property:

echo $xml->Course->CourseName;
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi!

Apparently you get NULL, but PHP is also sending a warning:

Warning: simplexml_load_string() expects parameter 1 to be string, object given

because $values->getCourseDetailResult is an object, and outputs:

stdClass Object
(
    [any] => XML is here ...
)

So change your previous:

$xml = simplexml_load_string($values->getCourseDetailResult);

To:

$xml = simplexml_load_string($values->getCourseDetailResult->any);

and it should work fine.

cereal 1,524 Nearly a Senior Poster Featured Poster

You can remove /usr/bin. When not sure about the path of a command you can use env, e.g.:

/usr/bin/env php script.php --attribute hello --import ../world.txt

but not in case of cd, you don't need it.

In any case I'm not sure the above script will work, because the --file attribute is the equivalent of the -f flag, used by the PHP CLI SAPI to define a script or a file to execute, from man php:

--file file
-f file        Parse and execute file

I see that in your tutorial this is used to define a file to import in the script. If you see you cannot get it to work, then change the attribute to something else, like --import and then in the code just replace:

$this->getArg('file')

with:

$this->getArg('import')

then it should work fine.

cereal 1,524 Nearly a Senior Poster Featured Poster

@k_manimuthu

Hi,

the FROM statement is not allowed in the update query, this is reason you get the error. This will work:

UPDATE tb2,tb1 SET tb2.data = tb1.data WHERE tb1.id = tb2.id AND tb2.data IS NULL;

Which is almost the same of your previous query with Reverend Jim fix to match nulls. In alternative you can use a subquery:

UPDATE tb2 SET tb2.data = (SELECT data FROM tb1 WHERE tb1.id = tb2.id) WHERE tb2.data IS NULL;
cereal 1,524 Nearly a Senior Poster Featured Poster

Check also unsplash.com

cereal 1,524 Nearly a Senior Poster Featured Poster

Then check the contents of the debugger:

print_r($this->email->print_debugger());

You should be able to see the encoding, which is also visible looking at the headers of the received mail, but you should also be able to see if the connection to the SMTP server was done in UTF8 mode, for example:

250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8                 <- this
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

regarding the ffmpeg execution in $RF->newname are you returning only the filename or also the path in which this file is located? Is the destination path writable?

Regarding the execution of the controller from CLI, it seems you are autoloading the session library, this will give the kind of warnings and notices you are experiencing, solution is to load the session into each controller or to extend the session library to detect CLI requests:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Session extends CI_Session
{
    public function __construct()
    {
        $CI = get_instance();
        if($CI->input->is_cli_request())
            return;

        parent::__construct();
    }
}

Just save it into application/libraries/MY_Session.php.
Source: http://stackoverflow.com/a/8394485

cereal 1,524 Nearly a Senior Poster Featured Poster

does it shows the full path for file

No, the aliased path will not be directly accessible or visible so, only /uploads/file.ext will be visible to clients. There are some constraints, so read the documentation carefully.

OsaMasw commented: thanks +0
cereal 1,524 Nearly a Senior Poster Featured Poster

Also explain the reason, because you could simply use the Alias directive to point the external directory to clients:

Alias /uploads /etc/mnt/storage/uploads

that way you don't have to alter your scripts, but if your boss decision was taken for security reasons, then Alias is the wrong solution.

OsaMasw commented: I like this solution +2
cereal 1,524 Nearly a Senior Poster Featured Poster

If you can use the command line then use ffmpeg with the -vframes option, example here:

Through PHP you can use exec() or you can use this PHP-FFMpeg that supports -vframes

cereal 1,524 Nearly a Senior Poster Featured Poster

I see, thanks for sharing your solution! Besides my regular expression pattern was wrong, sorry for that... here's an updated version to match only \n:

$pattern = '/^([\\\\]?n|[\n])(.*)+$/';

This will catch the line feed and the \n when single quoted, in fact if you do:

$a = '\n';
echo ord($a);

You get 92 instead of 10, because it matches just the backslash. The above expression instead searches for both situations, here's a new example:

<?php

    $array = array(
        array('C1TEXT' => 'test'),
        array('C1TEXT' => '\nb'),       # single quotes
        array('C1TEXT' => "\na"),       # double quotes
        array('C1TEXT' => '\r'),
        array('C1TEXT' => '0003'),
    );

    foreach($array as $list => $lvalue)
    {
        foreach($lvalue as $key => $value)
        {
            preg_match('/^([\\\\]?n|[\n])(.*)+$/', $value, $match);
            if($match)
                unset($array[$list]);               
        }
    }

    print_r(array_merge($array));

The ending array_merge() will reindex the array and outputs:

Array
(
    [0] => Array
        (
            [C1TEXT] => test
        )

    [1] => Array
        (
            [C1TEXT] => \r
        )

    [2] => Array
        (
            [C1TEXT] => 0003
        )

)

Doing a one more step, you can use the pattern to match the carriage return, as for the line feed echo ord('\r') returns 92 instead of 13, but you can do a switch to catch the second character, i.e. r, for example:

foreach($array as $list => $lvalue)
{
    foreach($lvalue as $key => $value)
    {
        preg_match('/^([\\\\]?(n|r)|[\n|\r])(.*)+$/', $value, $match);

        if($match)
            switch(ord($match[2]))
            {
                # n
                case 110:

                # "\n" assumes 0 because:
                # $match[0] & [1] will return 10 and
                # $match[2] will be empty
                case 0:
                    unset($array[$list]);
                    break;

                # r
                case 114: …
gabrielcastillo commented: Great solution. +4
cereal 1,524 Nearly a Senior Poster Featured Poster

The function array_walk_recursive will set the index key as second argument of the mapped function, the third argument will be the third of the function, since ltrim takes only two arguments it's better to define a custom function.

Now, the main problem is that array_walk_* cannot modify the structure of the array, so you cannot unset an index from the array, but you can change a value, in order to do this you must not return but simply set the value, basically:

function a(&$value, $key, $options)
{
    if(... condition ...)
        $value = '';
}

Note the reference &$value, otherwise the change is not registered by the original array.

The other problem is represented by the quotes, if in the array \n is surrounded by single quotes, then it is not consider a line feed character, but two separated characters, if instead you use double quotes you have a line feed:

$a = '\n';    # two chars
$b = "\n";    # line feed

Now, you can use a regular expression to match both cases, a pattern like this '/[\n\-n](.*)+$/' should work, and this is the full example:

<?php

    function _ltrim(&$value, $key)
    {
        preg_match('/[\n\-n](.*)+$/', $value, $match);
        if($match)
            $value = '';
    }

    $array = array(
        array('C1TEXT' => 'test'),
        array('C1TEXT' => '\n'),    # single quotes
        array('C1TEXT' => "\n"),    # double quotes
        array('C1TEXT' => '\r'),
        array('C1TEXT' => '0003'),
        );

    array_walk_recursive($array, '_ltrim');
    print print_r($array) . PHP_EOL;

It will output:

Array
(
    [0] => Array
        (
            [C1TEXT] => test
        )

    [1] => Array
        ( …
gabrielcastillo commented: very helpful +4
cereal 1,524 Nearly a Senior Poster Featured Poster

Would those be in the same file or separate?

You can use both methods, by default the Windows setup will use a single file, httpd-vhosts.conf, as defined by httpd.conf. But you can change the statement to include any .conf file in the defined directory, for example:

IncludeOptional conf/sites-enabled/*.conf