codeigniterใช้ database แล้ว include smf ssi มัน error ครับผม
http://codeigniter.com/forums/viewthread/162090/
Date :
2010-10-23 16:36:23
By :
:)
ผมว่าน่าจะเป็นปัญหาเหมือนในกระทู้ข้างบนแหละครับ :D
Date :
2010-10-23 16:40:17
By :
num
ไม่คล้ายกับปัญหาข้างบนนั่นแม้แต่นิดเดียวครับ
Date :
2010-10-23 18:17:35
By :
mr.v
แวะมาอ่าน ...
Date :
2010-10-24 11:38:16
By :
DS_Ohm
directory ใน Settings.php ของผมก็ตรงตาม pathของ server แล้วน่ะครับ
นอกนั้นก็ค่า default ของ smf ทั้งหมด :S
http://demo.okvee.net/testci/test.php
มันมากจาก server setting ไม่เหมือนกันรึเปล่าครับ ผมละสงสัยตรง mysql. persistent ต่างๆ
mysql.allow_persistent
mysql.max_persistent
ว่าแต่คุณหนุ่มกำหนด error E_ALL รึเปล่าครับ
ประวัติการแก้ไข 2010-10-24 12:54:54 2010-10-24 12:57:55
Date :
2010-10-24 12:46:17
By :
mr.v
E_ALL ครับ หน้า http://demo.okvee.net/testci/
แสดงกระทู้ได้แล้วนิครับ
แต่ทำไมถึงมีการเรียก mysql_query ซ้ำจนทำให้เกิด error ได้อีกอันนี้อาจจะเกิดจากคำสั่งอื่นที่ไม่ใช่ ssi_recentTopics ป่าวครับ
Date :
2010-10-24 13:41:12
By :
num
ไม่มีคำสั่งอื่นเลยครับ ทั้งหมดตรงตามที่ซิปไว้ให้ดาวน์โหลดเป๊ๆ ยกเว้นตรง config db ต่างๆ กับ path ต่างๆที่แตกต่างกันเท่านั้นครับ
มันแสดงกระทู้ได้ครับ ถูกต้อง แต่ผมติดตรงที่มันมี error นี่แหละที่บน windows มันไม่เป็น
ตรง mysql_query() ที่ error เท่าที่ดูทุกอย่าง smf ก็ทำออกมาอย่างถูกต้องเป๊ๆะด้วยครับ
แม้จะเหลือแค่ ssi_recentTopics มันก็ยัง error อยู่ดีครับ
ชีวิตมันยาก
-----------
ข้อมูลเพิ่มเติม
ผมทดลองปรับแต่ง php.ini บนเครื่องของผม windows
mysql.max_links = -1 ปรับเป็น 1 แล้ว restart apache
ปรากฏว่ามัน error เหมือนหน้าเว็บเป๊ะๆเลยครับ
ตามลำดับด้วย
Sources/Subs.php
Sources/Errors.php
Sources/Errors.php
แต่ต่างกันตรงที่ไม่แสดงกระทู้เท่านั้นเอง
ผมเลยเข้าใจว่า codeigniter มันไปปิดการเชื่อมต่อของไฟล์ที่ถูก include เข้ามา ตรงนี้ผมหาไม่เจอและแก้ไม่เป็นอ้ะ
--- แต่ว่าๆ
http://demo.okvee.net/testci/test.php ใน server จริง mysql maxlink มันก็ unlimit นะครับ
แล้ว codeigniter มันไปตัดการเชื่อมต่อ db ตรงไหนของมัน
ประวัติการแก้ไข 2010-10-24 15:27:12 2010-10-24 15:32:16
Date :
2010-10-24 15:05:38
By :
mr.v
โอว กระทู้จะหล่นแล้ว
ไม่มีใครช่วยผมได้จริงๆเหรอครับเนี่ย..
Date :
2010-10-26 16:14:55
By :
mr.v
ใช้วิธี var_dump(debug_backtrace()); ในไฟล์ที่เกิด error ครับ (่ก่อนหน้าคำสั่ง mysql_query)
แทรกหลายๆ ที่ครับ แล้วตรวจดูว่า db_connection เปลี่ยนไปตอนไหน
echo '[1]';var_dump(GLOBALS['db_connection']);
echo '[2]';var_dump(GLOBALS['db_connection']); //เปลี่ยน echo [2] แทนเพื่อจะรู้ว่า db_connection เปลี่ยนไปตอนไหน
เวลาไม่มี debugger ก็ต้อง manual แบบนี้ครับ
Date :
2010-10-26 16:29:43
By :
num
echo '[1]';var_dump($GLOBALS['db_connection']);
ลืมตัว $ ไปครับ
Date :
2010-10-26 16:32:50
By :
num
ไม่เคยใช้ smf อ่ะ TT คงให้คำแนะนำไม่ได้
ไม่ทราบว่า SSI นี่คืออะไรเหรอคับ
Date :
2010-10-26 20:19:12
By :
pjgunner.com
ลองไล่ดูแล้วเกิดจากไฟล์ /forum/Sources/Load.php function reloadSettings () หรือเปล่าไม่แน่ใจ...
แถวๆบรรทัด 153
Code (PHP)
if (($modSettings = cache_get_data('modSettings', 90)) == null)
{
$request = db_query("
SELECT variable, value
FROM {$db_prefix}settings", false, false);
$modSettings = array();
if (!$request)
db_fatal_error();
while ($row = mysql_fetch_row($request))
$modSettings[$row[0]] = $row[1];
mysql_free_result($request);
// Do a few things to protect against missing settings or settings with invalid values...
if (empty($modSettings['defaultMaxTopics']) || $modSettings['defaultMaxTopics'] <= 0 || $modSettings['defaultMaxTopics'] > 999)
$modSettings['defaultMaxTopics'] = 20;
if (empty($modSettings['defaultMaxMessages']) || $modSettings['defaultMaxMessages'] <= 0 || $modSettings['defaultMaxMessages'] > 999)
$modSettings['defaultMaxMessages'] = 15;
if (empty($modSettings['defaultMaxMembers']) || $modSettings['defaultMaxMembers'] <= 0 || $modSettings['defaultMaxMembers'] > 999)
$modSettings['defaultMaxMembers'] = 30;
if (!empty($modSettings['cache_enable']))
cache_put_data('modSettings', $modSettings, 90);
}
ซึ่งถ้า comment ตรง db_query และที่เกี่ยวข้องลงมาจนถึง mysql_free_result นั้น รวมทั้งไล่ comment function ที่ถูกเรียกในหน้า SSI จนเหลือแต่ reloadsettings มันจะไม่มี error เหลือเลย งงมาก
แต่ถ้า comment ในฟังก์ชั่นนี้แล้วไปเปิด function ต่างๆมันก็ error อย่างอื่นไปเพราะส่วนนี้มันหายไป
ไม่รู้จะเช็คยังไงแล้ววครับ $db_connection ถูกลบอย่างไร้ร่องรอยเมื่อเอามันมา include กับ codeigniter
var_dump(debug_backtrace()); อันนี้ผมไม่รู้จะตรวจยังไงครับเพราะมันมีแต่ array อะไรเต็มไปหมดดูไม่มีอะไรน่าจะเกี่ยวหรือดูรู้เรื่องเลย
Date :
2010-10-27 02:28:58
By :
mr.v
echo '[1]';var_dump($GLOBALS['db_connection']);
if (($modSettings = cache_get_data('modSettings', 90)) == null)
{
echo '[2]';var_dump($GLOBALS['db_connection']);
$request = db_query("
SELECT variable, value
FROM {$db_prefix}settings", false, false);
$modSettings = array();
if (!$request)
db_fatal_error();
while ($row = mysql_fetch_row($request))
$modSettings[$row[0]] = $row[1];
mysql_free_result($request);
echo '[3]';var_dump($GLOBALS['db_connection']);
// Do a few things to protect against missing settings or settings with invalid values...
if (empty($modSettings['defaultMaxTopics']) || $modSettings['defaultMaxTopics'] <= 0 || $modSettings['defaultMaxTopics'] > 999)
$modSettings['defaultMaxTopics'] = 20;
if (empty($modSettings['defaultMaxMessages']) || $modSettings['defaultMaxMessages'] <= 0 || $modSettings['defaultMaxMessages'] > 999)
$modSettings['defaultMaxMessages'] = 15;
if (empty($modSettings['defaultMaxMembers']) || $modSettings['defaultMaxMembers'] <= 0 || $modSettings['defaultMaxMembers'] > 999)
$modSettings['defaultMaxMembers'] = 30;
if (!empty($modSettings['cache_enable']))
cache_put_data('modSettings', $modSettings, 90);
}
echo '[4]';var_dump($GLOBALS['db_connection']);
ส่วนการแสดง debug_backtrace หน้าคำสั่ง mysql_query เพื่อตรวจดูว่าก่อนหน้าเรียกคำสั่งนี้มีการเรียกไฟล์และฟังค์ชั่นอะไรมาก่อนบ้างครับ
จะไ้ด้ค่อยๆ ไล่โค้ดแบบด้านบนนี้ ให้ไปหาจุดที่เป็นปัญหาครับ
Date :
2010-10-27 06:13:31
By :
num
หมดหนทางครับ หาไม่เจอ
ถ้าใน Controller เอาการเชื่อมต่อ database ทุกอย่างออกหมด เหลือแต่ $this->load->database(); มันก็ยัง error อยู่ดี
แต่ถ้าเอา load->database() ออก ทุกอย่างจะปกติดี
โค้ดของ smf ก็ปกติดีอยู่แล้ว
คิดว่าน่าจะเป็นที่ codeigniter นั่นแหละไปรบกวนอะไรบางอย่างของ smf หลังจากที่ถูก include เข้าไป
เพราะตัว CI เองก็ชอบไปแทรกแซงส่วนพื้นฐานต่างๆให้พิกลพิการอยู่ อย่างเช่น $_GET ที่ถูกลบไม่ให้ใช้เป็นต้น
จากที่ลองดูแล้วก็หาต้นตอใน smf ไม่เจอ หายังไงก็หาไม่เจอจริงๆครับ เพราะตัวมันเองทำงานถูกต้องโค้ดถูกต้องแล้ว แต่ถูกทำลาย connection โดย codeigniter จากตรงไหนก็ไม่รู้
ลงท้ายก็ขอสรุปเอาเองว่ามันเป็นอะไรที่ตีกันและไม่มีวันเข้ากันได้ (ถ้าใช้ load->database() ใน controller ของ CI และไม่ include smf SSI.php แบบ http://).
น่าเศร้า =_="
-------------------
ขอบคุณ คุณหนุ่ม
ประวัติการแก้ไข 2010-10-27 14:14:05
Date :
2010-10-27 14:12:04
By :
mr.v
function Index()
{
ob_start();
include(dirname(dirname(dirname(dirname(__FILE__))))."/forum/SSI.php");
ssi_recentTopics('5');
$this->smf_topics = ob_get_clean(); //เอาตัวแปรนี้ส่งให้ไฟล์ view ครับ
parent::Controller();
$this->load->database();
}
ถ้าจำเป็นต้องใช้ buffer แทนครับ
Date :
2010-10-27 14:52:36
By :
num
ไม่ได้ผลครับ เหมือนเดิม.
Date :
2010-10-27 17:30:43
By :
mr.v
อยากช่วยครับ แต่ไม่เคยใช้ SMF น่ะครับ
Date :
2010-10-27 17:46:25
By :
webmaster
codeigniter มีการใช้ autoload library ป่าวครับ เพราะโค้ดนี้ทำงานก่อนที่จะเริ่มต้น connect db ของ codeigniter อีกครับ
คิดว่าจะไม่มีส่วนที่ codeigniter แทรกการทำงานของโค้ด smf ได้นะครับ
Date :
2010-10-27 18:01:20
By :
num
ไม่มี auto loadเลยครับ เพราะลองจากค่าแรกของ codeigniter เลย
มันแทรกการทำงานได้อย่างคาดไม่ถึงแหละครับ เพราะทั้ง controller, view อยู่ใน codeigniter มันแทรกหมดเลยครับ
ขนาดไฟล์ไม่ปิด ?> มันยังทำงานได้
$_GET ที่เป็นการรับค่าปกติจาก php มันก็ลบซะเกลี้ยง
แค่เพียง include ssi.php เข้าไปพร้อมโหลด databaseไม่ว่าก่อนหรือหลังมันก็เดี้ยงหมดครับ
เพราะ CI มันไม่ทำงานเหมือนหน้า php โดดๆที่เราเคยเขียนๆกัน มันโหลดยังไงของมันก็ไม่รู้ ทุกอย่างถูกเอาไปตรวจก่อนแล้วจึงทำงาน ประมาณนี้น่ะครับ คือถูกแทรกไปหมดก่อนแล้วจึงทำงานแสดงผลออกมา
ประวัติการแก้ไข 2010-10-27 18:34:59
Date :
2010-10-27 18:32:44
By :
mr.v
มันคงตีกัน include แบบ file จะเข้ากันไม่ได้จริงๆน่ะแหละครับ หมดปัญญาจะแก้
Date :
2010-10-27 18:35:46
By :
mr.v
ผมไม่แน่ใจว่า สถาปัตยกรรม CI เป็นอย่างไร (ไม่ทราบว่า CI เองสามารถคอนเนกต์ ทีละหลายคอนเนกชั่นได้หรือป่าว?)
ส่วน smf เอง ผมคิดว่า ถ้าไม่ได้รวมไปกับ CI ผมคิดว่า มันน่าจะรันด้วยตัวของมันเองได้ ผมไม่รู้ว่าคุณกำลังจะเอา smf ไปใส่ใน CI หรือป่าว ทั้งที่ผมคิดว่าเราสามารถแยกการทำงาน ส่วนใครส่วนมันได้
Date :
2010-10-27 21:54:09
By :
pjgunner.com
ผมก็คิดว่าอย่างนั้นครับ ตัว CI เองเชื่อมต่อฐานข้อมูลได้ครั้งละหลายๆตัวอยู่แล้ว สบายๆ
แต่ว่าเพียงแค่ load->database() ใน controller แล้ว include smf SSI.php เข้าไปโดยที่ยังไม่ต้องใส่ฟังก์ชั่นอะไร มันก็ไปซะแล้ว
และมันก็เป็นแค่บน server linux จริง
server windows จริงไม่มีให้ลอง
แต่บนเครื่องผมที่ปรับแต่ง php.ini ค่อนข้างรัดกุมก็รันผ่านหมด
-----
ตอบที่ค้างๆสำหรับคนอื่นๆที่ตอบมา
SSI ของ smf คือไฟล์ที่ใช้ include เข้าไปโดยใช้ได้ทั้ง include แบบไฟล์ และแบบ URL
เพื่อให้มีการแสดงกระทู้บนหน้า web page
คุณวินอยากจะช่วยผมก็ขอบคุณแล้วครับ ขอบคุณทุกๆคนด้วยครับ
ประวัติการแก้ไข 2010-10-27 22:45:46
Date :
2010-10-27 22:43:23
By :
mr.v
เสียดายไม่เคยใช้ CI
จริงๆ น่าจะแฮคได้อยู่
เท่าที่เดา (เดานะ)
คือคลาส วิว หรืออะไรที่เกี่ยวกับ วิว มันไม่ได้เป็น global scope เพราะว่ามันอยู่ใน ฟังชั่นหรือ คลาสเมธอดอีกทีอีกที
การใช้ global $db_connection อาจไม่พบ ตัวแปรของมัน ดังนั้น อาจหาวิธี สร้าง $db_connection ไว้ก่อน ในกรณีที่เรียกจาก คอนโทรเลอร์ของ CI และไม่ต้องสร้าง connection ใหม่ใน SSI.php ในกรณีเดียวกัน
sub.php
// Do a query. Takes care of errors too.
function db_query($db_string, $file, $line)
{
global $db_cache, $db_count, $db_connection, $db_show_debug, $modSettings;
static $conn2;
if (defined('IS_CI'))
{
if ( ! $conn2)
{
// create connection to $conn2
}
}
// One more query....
$db_count = !isset($db_count) ? 1 : $db_count + 1;
// Debugging.
if (isset($db_show_debug) && $db_show_debug === true)
{
// Initialize $db_cache if not already initialized.
if (!isset($db_cache))
$db_cache = array();
if (!empty($_SESSION['debug_redirect']))
{
$db_cache = array_merge($_SESSION['debug_redirect'], $db_cache);
$db_count = count($db_cache) + 1;
$_SESSION['debug_redirect'] = array();
}
$db_cache[$db_count]['q'] = $db_string;
$db_cache[$db_count]['f'] = $file;
$db_cache[$db_count]['l'] = $line;
$st = microtime();
}
// First, we clean strings out of the query, reduce whitespace, lowercase, and trim - so we can check it over.
if (empty($modSettings['disableQueryCheck']))
{
$clean = '';
$old_pos = 0;
$pos = -1;
while (true)
{
$pos = strpos($db_string, '\'', $pos + 1);
if ($pos === false)
break;
$clean .= substr($db_string, $old_pos, $pos - $old_pos);
while (true)
{
$pos1 = strpos($db_string, '\'', $pos + 1);
$pos2 = strpos($db_string, '\\', $pos + 1);
if ($pos1 === false)
break;
elseif ($pos2 == false || $pos2 > $pos1)
{
$pos = $pos1;
break;
}
$pos = $pos2 + 1;
}
$clean .= ' %s ';
$old_pos = $pos + 1;
}
$clean .= substr($db_string, $old_pos);
$clean = trim(strtolower(preg_replace(array('~\s+~s', '~/\*!40001 SQL_NO_CACHE \*/~', '~/\*!40000 USE INDEX \([A-Za-z\_]+?\) \*/~'), array(' ', '', ''), $clean)));
// We don't use UNION in SMF, at least so far. But it's useful for injections.
if (strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0)
$fail = true;
// Comments? We don't use comments in our queries, we leave 'em outside!
elseif (strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, ';') !== false)
$fail = true;
// Trying to change passwords, slow us down, or something?
elseif (strpos($clean, 'sleep') !== false && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0)
$fail = true;
elseif (strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0)
$fail = true;
// Sub selects? We don't use those either.
elseif (preg_match('~\([^)]*?select~s', $clean) != 0)
$fail = true;
if (!empty($fail))
{
log_error('Hacking attempt...' . "\n" . $db_string, $file, $line);
fatal_error('Hacking attempt...', false);
}
}
$ret = defined('IS_CI')
? mysql_query($db_string, $conn2)
: mysql_query($db_string, $db_connection);
if ($ret === false && $file !== false)
$ret = db_error($db_string, $file, $line);
// Debugging.
if (isset($db_show_debug) && $db_show_debug === true)
$db_cache[$db_count]['t'] = array_sum(explode(' ', microtime())) - array_sum(explode(' ', $st));
return $ret;
}
ประวัติการแก้ไข 2010-10-28 10:05:20 2010-10-28 10:15:42
Date :
2010-10-28 09:53:50
By :
pjgunner.com
เมื่อวานขอเข้าไปแก้ไขจนพอใช้ได้ละนะ แต่ยังไม่มีเวลาแกะจนรู้สาเหตุที่แท้จริง
สาเหตุน่าจะเกิด scope ตัวแปร global อย่างเช่นคุณเอี่ยวบอกไว้
หรือไม่ก็อาจเกิดจาก handler ของ codeigniter หรือ smf เข้าไปเปลี่ยนแปลงค่าตัวแปร
Date :
2010-10-28 10:26:18
By :
num
แวะมาอ่านด้วยคน
Date :
2010-10-28 10:27:57
By :
SOUL
ลองแก้ดูหลายๆ แบบสุดท้ายแค่แก้ในไฟล์ view ของ codeigniter โดยเพิ่มคำสั่งให้ตัวแปร global อ้างอิงไปยังตัวแปร $db_connection
<?php include(dirname(dirname(dirname(dirname(__FILE__))))."/forum/SSI.php"); ?>
<?php ssi_recentTopics('5'); flush(); ?>
<?php $GLOBALS['db_connection2'] = $db_connection; ?>
Date :
2010-10-28 10:29:37
By :
num
โอ้... ขอบคุณทั้งสองมากๆเลยครับผม ผมถอดใจสู้กะมันไปแล้วนะเนี่ย อย่างนี้ต้องกลับไปแก้ซะแล้ว 55
Date :
2010-10-28 16:10:32
By :
mr.v
ของกำนัล
Date :
2010-10-28 16:29:13
By :
mr.v
Date :
2010-10-28 16:30:37
By :
num
Load balance : Server 02