Chauronslilsis wrote:
Can't wait to see the finished product. It looks like you've put your whole heart into this and that's what makes this so amazing! Best of luck Comic! <3
Thanks! There's a few hurdles that I may be unable to tackle by myself and will solicit help from some friends who have some specialized experience in the matter but that's not any time soon Very Happy
Well, the site* is done enough to be presentable. I still have work to do on a few things: Descriptions of individual portfolios, costs of services, the contact page, and to flesh out the "about" details a bit better. Sadly, I'm at an impasse. I would like to add Previous & Next links to my images so it's easier to navigate when looking at a single image but due to the nature and volatility of my image portfolios I am unable to assign a numerical ID number to the rows. Here's how my image table is setup:


Code:

The Filename | The UID | ... | Keywords
---------------------------------------
IMG_0001.jpg | abcd123 | ... | Landscape,Infrared
IMG_0018.jpg | abxy36d | ... | Portrait
IMG_0131.jpg | 1245abc | ... | Sports
IMG_0136.jpg | a1b2c3d | ... | Wedding


I have no ID column that counts consecutively. All photos are under one database, adding in row numbers would only be logical if I were to show images in order, or to have one database per portfolio but since I am only grabbing the images with the keywords that match the portfolio, I could have row numbers 5,6,8,22 and 23. Secondly, the nature of the portfolios. I could add 5 images and remove 3 on any given day. These images aren't going to stay in the database for ever. Before, I only limited my portfolios to nine images but now some have way more. I'm not limiting myself to a certain number but after a while photos may not represent the work I desire to show.

I have yet to play around here but how does LIMIT work? Could I select rows of my database that match the keyword and select the rows I want to show that way? In essence, does MySQL know I have 5 rows, I'm on row 2 and to select rows 1 and 3? Obviously I'd have to tell it I'm on row X and I want X-1 & X+1. I plan to test this tomorrow if I don't get a response, though. Just curious if this is the correct way or if there is a better way.

*If the link doesn't work, http://alextakespics.com is a link that works on older or otherwise incompatible browsers with the new top level domains.
So, LIMIT will work the way I want it to. Now, I'm trying to discover which row of the result the requested photo is on and I'm sure if I had sequential row numbers, it'd be easier.

Anyways, here's my code to get this to work:


Code:
   // Create the query to select only the image we need.
   $sql       =      "SELECT * FROM Table WHERE uid='$i'";
   // Run the query
   $query       =       mysqli_query($con,$sql);
   
   // This variable is how we determine what row the requested picture is on
   $arn       =       0;
   
   // This will fetch every image that matches the service selected,
   // ordering by the newest date first then oldest image first.
   $simge      =      "SELECT * FROM Table WHERE keywords LIKE '%$s%' ORDER BY date DESC, time ASC";
   // Since we run a different query
   $simg    =       mysqli_query($con,$simge) or die(mysqli_error($con));
   
   echo "Hello: arn";
   while(mysqli_fetch_assoc($query) != mysqli_fetch_assoc($simg)) {
      echo "$arn<br>";
      $arn++;
   }
   // Since we want to make the next and previous "buttons"
   ## $arn is where the current image resides in this result
   ## And we are fetching two images after it.
   $pwheel       =      $simge . " LIMIT $arn,2";
   // I still need to code the previous "buttons."


My plan was this. Use a while loop to increment $arn until a match was found. When the match is found, the loop quits and $arn is the value of the row with the matching image. However, with the way it is the while loop is never being triggered (as per my "debug echo" inside), if I remove the mysqli_fetch_assoc() around $query the page takes for ever to load, assuming I've entered an infinite loop. Which I can't tell as my debug echo never outputs and when I stop the page it still doesn't show.

Is there a better way to go about this? Am I overseeing a very simple error somewhere?

Update-Ish: I've switched $query and $simg and it works, sorta. I get loops for however many images are in each portfolio. 9 for the portraits, 14 for the weddings, etc etc. If I click the first image I get only 1 loop. It seems I'm missing a catch for when the picture is not the first result but I can't quite find out how, since the while() should stop when the condition is true/matches.

I presume it did not work before because it was only looping once, as $query only has one result while $simg has more. Now that $simg is in the front, it loops the amount of times that there are rows.

Last Bump: It sounds like I may want to do a do ... while function?

This is not any better; In this case it either loops twice or through every image. You'll note the two lines switched places, this is to reflect the last value of the variable. Before, $arn would be the last value that was updated before it was false, in this case $arn can be updated even after the condition is false. So, to show me what the code will see, I output $arn at their latest values so I can adjust them later. If I were to update the value of $arn below after printing the value, not only would the output be incorrect I may not correct for this when coding beyond the debug info.

Code:
      do {
         $arn++;
         echo "$arn<br>";
      } while(mysqli_fetch_assoc($simg) != mysqli_fetch_assoc($query));
Question: For the pages that don't load, are you examining the PHP error logs to see why the pages did not load, or don't you have access to these? Are you running this code on Amethyst or elsewhere? I need to read this more carefully, but I suspect you might want some unique, auto-incrementing column in your table for uniquely identifying the row you find when you find the row you want. In fact, if you have a unique numeric identifier, I don't think you'd have to search at all. Or if you're searching by hash, please oh please cache that hash in the table to turn an O(n) search into an O(log(n)) search.
KermMartian wrote:
Question: For the pages that don't load, are you examining the PHP error logs to see why the pages did not load, or don't you have access to these?


I am not looking at error logs. It never occurred to me, mostly because I either get an Error: Line # and can diagnose it from there. Secondly, the pages load fully according to the browser but it seems I'm not exiting the loop when a match is found, suggesting a match isn't found. But, when I click the first image the loop successfully ends.

Edit: See, http://alex.takes.pics/?t=portrait which has 9 photos.
Click first image. One loop.
Click second image. 9 loops.
Click any image from 2 through 9. 9 loops.

It's also worth noting I'm using while() instead of do {} while() again.

Second Edit: I revised my debug echos and discovered I'm not even entering the While loop when clicking the first photo, presumably since the statement is already true.


Quote:
Are you running this code on Amethyst or elsewhere?


Elsewhere. I could move to Amethyst but I got a good deal on web space when buying another domain name.

Quote:
I need to read this more carefully, but I suspect you might want some unique, auto-incrementing column in your table for uniquely identifying the row you find when you find the row you want.


I don't think such a thing is possible. I have all [service] photos in one table. I have 30 photos total in this table while I have 14 in Weddings, 10 in Portraits, etc etc. If I had one table per portfolio it could happen but I'd need to insert data into multiple tables and I wouldn't be as flexible in expanding portfolios. If I had a table for Infrared and a second for Portraits, I could save the photo details to each table. If I had a photo that was both infrared and a portrait I could save it twice. However, if I ever want to add an Emotive portfolio and this photo (and any prior photos) were also keyworded with "Emotional" or "Emotive" I'd have to add a new table and reprocess the all the photos so they could be saved into the respective table.

By keeping all my photos under one table, I can add new services and portfolios in a snap. Name the portfolio in the CP and select an image for the thumbnail and it's done. I think introducing multiple tables is going to complicate the code I have to write for the CP. It just seems simpler to have everything in one table for now.

Quote:
In fact, if you have a unique numeric identifier, I don't think you'd have to search at all. Or if you're searching by hash, please oh please cache that hash in the table to turn an O(n) search into an O(log(n)) search.


I search by hash, yes, and the hash in saved to the table as you'll notice in my example above. The hash is only used as a search when selecting a single image from the table.

Edit 3 & Update: Figured it out. I was improperly using a while loop. I came to that conclusion after using "while(($fetch_1 = mysqli_fetch_assoc($query)) != ($fetch_2 = mysqli_fetch_assoc($simg)))" and adding in print outs of the variables. Since $fetch_1 is only one row and $fetch_2 was 9, the script was drawing blanks for $fetch_1 while it counted rows for $fetch_2. Thus, #fetch_1 never equaled $fetch_2 since $fetch_1 was overwritten with NULL after the first loop. Which also explains why the loop wasn't executing when the first image was clicked, since both variables were equal.
Got around to finishing the Next & Previous links. When a user is at the first image, a placeholder is used for the "Previous" because if it weren't there, the "Next" image would be the first image and when they click the image for the "Previous" image would take it's place and the user would cycle between the First & Second images until they realized. Did the same thing with the last image in the portfolio as well. I plan to replace the placeholder images with something better, but for now a generic X will work.

I also created an RSS page, meaning you can now subscribe to my photo journal. If you're on the website, click the RSS link in the sidebar and let your computer/phone take it from there. For iOS users, it will open in the Podcasts app which is only compatible with audio/video feeds, not text/photo. The RSS feed is relatively dynamic. While both alex.takes.pics & alextakespics.com point to the same files, the RSS feed will generate a URL off whatever domain you choose. So, if you're device doesn't support the new gTLDs, you'll still be able to visit the links from the RSS feed. The whole RSS thing was much easier than I thought it'd be.

I think I'm more or less done, though. I should start thinking about adding pages to the journal side of the site. Might find time Monday to get that done.
Picked up a new DSLR a few days ago and have a new project. The DSLR has a built-in GPS and, besides geo-tagging pictures, logs the GPS position to internal memory which I can dump to the memory card for use on the included computer software. However, I got a different idea.

I want to upload this data to my website and create a section for hiking or trips. Use the GPS Logs to show the path on a static map image; eventually I'll move to a dynamic map with the locations of pictures along said path. Depending on the frequency of the updates, I can easily have upwards of 1000 lines of GPS data. I've processed more than one image before but my query was within a loop, so I still effectively processed one image at a time.

What's the best way to bulk add info into a MySQL table? I saw an example on StackExchange where I can do something like "INSERT (a,b,c) VALUES (1a,1b,1c),(2a,2b,2c),(3a,3b,3c),etc,etc". It seems ideal but I'd have a fairly large string at the end of the loop and may risk a memory error. Is my best option to repeat the query over and over until the file is imported or should I just scrap this all together?

Some insight on how I can easily achieve 1000 lines. The camera can record it's position in selectable intervals: 1 second, 5 seconds, 10, 15, 30, 1 minute, 2 minutes, 5 minutes.

At 01 seconds: ~016 minutes.
At 05 seconds: ~083 minutes or ~1.5 hours.
At 10 seconds: ~166 minutes or ~3.0 hours.
At 30 seconds: ~300 minutes or ~8.0 hours.

My hikes will usually last about 3 hours, so if I keep the frequency at 5 seconds, I'd see about 2,160 lines of data inserted. I've also been on longer adventures, of 9 hours, which would be 6,480 lines. It's hard to say "This will be a 3 hour hike" and set the frequency accordingly, as it could be 4 or 5 hours if you're walking with a group. I could always adjust the frequency on import. Grabbing every 10 seconds of data (every other line).


Update: I'm still reading up. I realized I am can output the whole data to a page with one variable (print_r(file_get_contents("path/to/file")); and that I can have a 3D(?) array. So, I can save each row in the array, then each row is another array and perform an implode(",",$data);

Is this another viable option? I suspect implode would only separate the first layer of the array and I'd have to implode the array again to go deeper?
Having some issues with my contact form. I got it up and running and have since duplicated the appropriate files to try and make the experience a bit more seamless. Before talking about what it's suppose to do, I have an error. On the public facing form I have no errors but on the private/test form I get an undefined index with the same code. The errors are on lines 10, 11, and 12 of the send script.

Pastebin, Send Script: Public vs Private

Pastebin, Form Page: Public vs Private
In both the Public and the Private versions, you have "message" in the PHP code but "Details" in the HTML markup. You'll never read the body of the message this way! Another problem: on line 31, you use $memty wrong. You define it as an integer, 0 if there was a missing required message and 1 if it doesn't matter or was filled. However, you then use it as if it was a string:
Code:
if(empty($memty))       echo '<li>The information regarding the selected service ("Other").</li>';
You say you get the undefined index error only on the private page, but I'm pretty sure you simply aren't getting that level of verbosity on the public-facing version. Presumably you're setting a higher error verbosity on the private side?
KermMartian wrote:
In both the Public and the Private versions, you have "message" in the PHP code but "Details" in the HTML markup.

Thanks for spotting that, adding Details into the send.php alleviated the undefined index on Line 12. I'll double check the other 2 to ensure this isn't the same error, which I doubt.

Quote:
Another problem: on line 31, you use $memty wrong. You define it as an integer, 0 if there was a missing required message and 1 if it doesn't matter or was filled. However, you then use it as if it was a string:
Code:
if(empty($memty))       echo '<li>The information regarding the selected service ("Other").</li>';

I don't understand how that's using it as a string - I was going to claim the code worked but it actually doesn't. Oops. Anyways, it's now if(!$memty) and works.

Quote:
You say you get the undefined index error only on the private page, but I'm pretty sure you simply aren't getting that level of verbosity on the public-facing version. Presumably you're setting a higher error verbosity on the private side?

Code:
   error_reporting(E_ALL);
   ini_set('display_errors', true);

This is in my header.php, which is called by both public and private. Which, I think you might be on to something. Since the same issue was on the public send.php (messages instead of Details) and the undefined index error wasn't present.


Update: For what it's worth, I simply changed the following and I get no more undefined index errors.

Code:
   if(isset($_POST['name']))      {$name          =    $_POST['name'];}      else {$name    = null;}
   if(isset($_POST['email']))      {$email       =    $_POST['email'];}      else {$email    = null;}
   if(isset($_POST['Copy']))      {$copy          =    $_POST['Copy'];}      else {$copy      = null;}
   if(isset($_POST['Type']))      {$type          =   $_POST['Type'];}      else {$type      = null;}
   if(isset($_POST['Details']))   {$message       =   $_POST['Details'];}      else {$mesasge   = null;}
comicIDIOT wrote:
KermMartian wrote:
Another problem: on line 31, you use $memty wrong. You define it as an integer, 0 if there was a missing required message and 1 if it doesn't matter or was filled. However, you then use it as if it was a string:
Code:
if(empty($memty))       echo '<li>The information regarding the selected service ("Other").</li>';

I don't understand how that's using it as a string - I was going to claim the code worked but it actually doesn't. Oops. Anyways, it's now if(!$memty) and works.
I was misinformed about how PHP's empty() function works. 0 is indeed considered "empty" by empty(), but I still don't love that for clarity.

Quote:
Update: For what it's worth, I simply changed the following and I get no more undefined index errors.
A small point of stylistic sanity: I recommend casing all of your field names the same way. Convention is all lowercase letters.
Indeed, I will eventually go back and make them all uniform. I copied the form code from my old website and just added on to it, hence the mishmash of capitalization.

comicIDIOT wrote:
My hikes will usually last about 3 hours, so if I keep the frequency at 5 seconds, I'd see about 2,160 lines of data inserted. I've also been on longer adventures, of 9 hours, which would be 6,480 lines. It's hard to say "This will be a 3 hour hike" and set the frequency accordingly, as it could be 4 or 5 hours if you're walking with a group. I could always adjust the frequency on import. Grabbing every 10 seconds of data (every other line).


I went on a hike today and it lasted just over 3 hours. I have some data to compare. For the sake of finer details, I checked my position every second. At the end of the day I have 21,460 lines of data. I mention that the camera saves two variants, GPGGA and GPRMC formatted data. So, divided by 2 and I'd have 10,730 lines of data imported into my database. If I decided to import every 5th second I'd have 2,146 lines.

I know databases can grow to many thousands of rows but it grows over time. Is importing 2k-10k rows recommended? If not, how do I go about it? Secondly, I see I can import multiple rows at once. Should I compile all the rows into one variable and send it to the DB or should I do it row by row, 5 rows by 5 rows, or what?
I've successfully managed to save my GPS logs to a database. Now, I'm getting the database info into a KML Googles Tutorial is in Object Oriented PHP, which I'm unfamiliar with.

I can create the KML Document and save it but none of my relevant information is getting saved to the document. In fact, despite what I'm led on to believe it's not looping or fetching anything from the table.

Here's my code. On line 51 it says "iterate through the results" but it does so without forming a loop that I'm familiar with and I suspect this is the source of my issue. But being new to this format of programming, I can't be sure.

This is my output:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
   <Document/>
      <Folder>
         <Placemark id="linestring1">
            <name>My path</name>
            <description>Where I hiked</description>
            <LineString>
               <extrude>1</extrude>
               <altitudeMode>relativeToGround</altitudeMode>
               <coordinates>3720.5642 12142.9563</coordinates>
            </LineString>
         </Placemark>
      </Folder>
</kml>


In a perfect world, all 8k rows of coordinates should be there too. Is @ a proper marker in OOP for a loop? If not, how do I loop this?
Also, unrelated but I just realized I need to reformat my coordinates.
comicIDIOT wrote:
Is @ a proper marker in OOP for a loop? If not, how do I loop this?
Oddly enough, you use a loop. For example:

Code:
                ## Iterate through the MySQL results
                while($row = @mysqli_fetch_assoc($result)) {
                        //... do something with row
                }
Hope that helps. Here's an explanation of the @ symbol: http://php.net/manual/en/language.operators.errorcontrol.php
Weird. Wonder why Google didn't implement a loop in their example/tutorial then. Thanks. What does the @ symbol mean in this scenario then?
comicIDIOT wrote:
Weird. Wonder why Google didn't implement a loop in their example/tutorial then. Thanks. What does the @ symbol mean in this scenario then?
KermMartian wrote:
Back at this, adding Google Maps to my website to visualize hikes and drives. Eventually plan to show photos taken along the path displayed but one step at a time.

Good news is, it works. I can zoom in select maps and stuff. Bad news is, it there's something somewhere that is causing a weird display issue. When I view the map index it's a blank page. When I add in what map I want to see, the map selection and map display are available.

In my page header, I have this:

Code:
   if(isset($_GET['h'])) {$ismap = TRUE;} else {$ismap = NULL;}
   if($ismap) {include('*/map_php.php');}
....
   <?php if($ismap) {include('map_script.php');} ?>


It's the only place that calls the map functions from the index. I suspect it has something to do with $_GET['h'] because when I change it to something else, like "$_GET['k']" then "$_GET['h']" displays the map selection but no map shows up when clicked.

A good example of how this should work would be this stand-alone page. Instead of index.php?h I have map.php. Map Selection is present. As soon as [url=http://alex.takes.pics/map.php?h]?h is added[/url], though, it's a blank page again. But when you load a map, it displays everything, just like the index.

map.php wrote:

Code:
<?php
   $ismap      = TRUE;
   $mapcon   =   mysqli_connect("**");
   $mapdb      = "**";
   $maptables   = "SHOW TABLES FROM $mapdb";
   $mapresult = mysqli_query($mapcon, $maptables);
   $latitude=null;
   $longitude=null;
   $user = "Alex";
   
   // Set the sub title for the page
   $header_title = " | Map";
   
   // $_GET
   if(isset($_GET['map'])) {$map = $_GET['map'];} else {$map = null;}
#   $map = htmlspecialchars($map);
   $map ="$user$$map"; 
   
   include_once('*/header.php');
   include_once('*/hiking.php');
   include_once('*/sidebar.php'); ?>


It calls the same page ?h does from the index:

index.php wrote:

Code:
} elseif(isset($_GET['h'])) {
                           include('*/hiking.php');


hiking.php wrote:

Code:
<?php
   include('map_sql.php');
   $mapdb      = "**";
   $maptables   = "SHOW TABLES FROM $mapdb";
   $mapresult = mysqli_query($mapcon, $maptables);
   $user = "Alex";
   
   echo "<ol>";
   while($row = mysqli_fetch_assoc($mapresult)) {
      $name   =   $row["Tables_in_$mapdb"];
      list($prefix,$file) = explode("$", $name);
      if($prefix == $user) echo("<li><a href=\"?h&map=$file\">$file</a></li>");   
   }
   echo "</ol>";
?>


I have the DB things repeated as I'm still in the getting things to work phase. I'll consolidate and optimize afterwards.

I'm 99% certain it's how I'm handling the "?h" that's causing this issue but I can't seem to understand why or how. Opinions? Thoughts?
It seems a bit silly that you're using NULL (instead of false) as the opposite of true. I would change:
Code:
   if(isset($_GET['h'])) {$ismap = TRUE;} else {$ismap = NULL;}
to
Code:
   $ismap = isset($_GET['h']))
isset() already returns true or false, so there's no need to wrap that extra conditional around if. I'm not sure if NULL evaluates to true or false in PHP (I'd hope false, but you never know).

Edit:

Code:
   if(isset($_GET['map'])) {$map = $_GET['map'];} else {$map = null;}
#   $map = htmlspecialchars($map);
   $map ="$user$$map";   
Bad bad bad bad bad. How do you use the variable $map? If it goes anywhere near MySQL, you have an SQL injection vulnerability. Never accept input from the user like that without sanitization.
KermMartian wrote:
(I'd hope false, but you never know).

I believe it does, as I have if(isset($_GET['info'])) in my code. I just wasn't thinking in this case, already changed.

Quote:
Edit: Bad bad bad bad bad. How do you use the variable $map?


It get's passed off the map_script.php, which is the javascript for the map with php to select every nth row, for extra detail it is currently every 120 lines for a frequency of 2 minutes between data points. Back to the point, I've uncommented htmlspecialchars and added in RegEx to strip the numerals from any input to it's own variable which then get's passed on.
It sounds like this would be a good time to investigate some inline debugging output to figure out what variables have what values where, especially right before whichever includes should cause PHP to display the header/sidebar. Here's a question: does map_php.php include the header and sidebar, or does map.php? And there's also map_script.php?
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 2 of 3
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement